semantifold 0.13.0 → 0.14.0

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.
Files changed (59) hide show
  1. package/README.md +1 -0
  2. package/build/src/backends/effects.js +3 -1
  3. package/build/src/backends/php.d.ts.map +1 -1
  4. package/build/src/backends/php.js +56 -3
  5. package/build/src/backends/scalars.js +2 -2
  6. package/build/src/backends/shared.d.ts +2 -1
  7. package/build/src/backends/shared.d.ts.map +1 -1
  8. package/build/src/backends/shared.js +209 -7
  9. package/build/src/backends/writer.d.ts +18 -4
  10. package/build/src/backends/writer.d.ts.map +1 -1
  11. package/build/src/backends/writer.js +40 -4
  12. package/build/src/frontends/java.d.ts +1 -1
  13. package/build/src/frontends/java.d.ts.map +1 -1
  14. package/build/src/frontends/java.js +14 -11
  15. package/build/src/frontends/javascript-typescript.d.ts +1 -1
  16. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  17. package/build/src/frontends/javascript-typescript.js +17 -17
  18. package/build/src/frontends/php.d.ts +5 -1
  19. package/build/src/frontends/php.d.ts.map +1 -1
  20. package/build/src/frontends/php.js +159 -31
  21. package/build/src/frontends/ruby.d.ts +1 -1
  22. package/build/src/frontends/ruby.d.ts.map +1 -1
  23. package/build/src/frontends/ruby.js +12 -9
  24. package/build/src/frontends/types.d.ts +9 -2
  25. package/build/src/frontends/types.d.ts.map +1 -1
  26. package/build/src/frontends/types.js +26 -9
  27. package/build/src/language-registry.d.ts.map +1 -1
  28. package/build/src/language-registry.js +14 -6
  29. package/build/src/mapping.d.ts.map +1 -1
  30. package/build/src/mapping.js +4 -2
  31. package/build/src/semantic/effects.d.ts.map +1 -1
  32. package/build/src/semantic/effects.js +3 -1
  33. package/build/src/semantic/provenance.d.ts.map +1 -1
  34. package/build/src/semantic/provenance.js +37 -4
  35. package/build/src/semantic/types.d.ts +140 -9
  36. package/build/src/semantic/types.d.ts.map +1 -1
  37. package/build/src/semantic/types.js +37 -6
  38. package/build/src/semantic/validate.d.ts +31 -2
  39. package/build/src/semantic/validate.d.ts.map +1 -1
  40. package/build/src/semantic/validate.js +346 -27
  41. package/docs/adr-bounded-subtyping.md +180 -0
  42. package/docs/language-support.md +1 -1
  43. package/package.json +1 -1
  44. package/src/backends/effects.js +1 -0
  45. package/src/backends/php.js +56 -2
  46. package/src/backends/scalars.js +1 -1
  47. package/src/backends/shared.js +210 -6
  48. package/src/backends/writer.js +41 -3
  49. package/src/frontends/java.js +13 -10
  50. package/src/frontends/javascript-typescript.js +16 -16
  51. package/src/frontends/php.js +175 -31
  52. package/src/frontends/ruby.js +11 -8
  53. package/src/frontends/types.js +26 -8
  54. package/src/language-registry.js +13 -5
  55. package/src/mapping.js +3 -1
  56. package/src/semantic/effects.js +1 -0
  57. package/src/semantic/provenance.js +34 -3
  58. package/src/semantic/types.js +39 -5
  59. package/src/semantic/validate.js +377 -26
@@ -106,6 +106,7 @@ export class SourceWriter {
106
106
  this.stdlibProviderShims = stdlibProviderShims
107
107
  const programRecords = program?.modules.flatMap((programModule) => programModule.records ?? []) ?? module.records ?? []
108
108
  const programClasses = program?.modules.flatMap((programModule) => programModule.classes ?? []) ?? module.classes ?? []
109
+ const programInterfaces = program?.modules.flatMap((programModule) => programModule.interfaces ?? []) ?? module.interfaces ?? []
109
110
  const capabilityFailures = module.capabilities?.flatMap(({failures}) => failures) ?? []
110
111
  const programErrors = program?.modules.flatMap((programModule) => [
111
112
  ...(programModule.errors ?? []),
@@ -115,6 +116,7 @@ export class SourceWriter {
115
116
 
116
117
  this.records = new Map(programRecords.map((record) => [record.id, record]))
117
118
  this.classes = new Map(programClasses.map((declaration) => [declaration.id, declaration]))
119
+ this.interfaces = new Map(programInterfaces.map((declaration) => [declaration.id, declaration]))
118
120
  this.errors = new Map(programErrors.map((error) => [error.id, error]))
119
121
  this.resources = new Map((module.capabilities?.flatMap(({resources}) => resources) ?? []).map((resource) => [resource.id, resource]))
120
122
  this.effectOperations = new Map((module.capabilities?.flatMap(({operations}) => operations) ?? []).map((operation) => [operation.id, operation]))
@@ -123,7 +125,14 @@ export class SourceWriter {
123
125
  this.fields = new Map(programRecords.flatMap((record) => record.fields.map((field) => [field.id, field])))
124
126
  this.fieldRecords = new Map(programRecords.flatMap((record) => record.fields.map((field) => [field.id, record])))
125
127
  this.privateFields = new Map(programClasses.flatMap((declaration) => declaration.fields.map((field) => [field.id, field])))
126
- this.methods = new Map(programClasses.flatMap((declaration) => declaration.methods.map((method) => [method.id, method])))
128
+ /** @type {Map<string, import("../semantic/types.js").InterfaceMethodDeclaration | import("../semantic/types.js").MethodDeclaration>} */
129
+ this.methods = new Map()
130
+ for (const declaration of programClasses) {
131
+ for (const method of declaration.methods) this.methods.set(/** @type {string} */ (method.id), method)
132
+ }
133
+ for (const declaration of programInterfaces) {
134
+ for (const method of declaration.methods) this.methods.set(/** @type {string} */ (method.id), method)
135
+ }
127
136
  this.typeParameters = new Map([...programRecords, ...programFunctions].flatMap((declaration) =>
128
137
  (declaration.typeParameters ?? []).map((parameter) => [parameter.id, parameter])))
129
138
  this.referenceClassEmissionDepth = 0
@@ -131,6 +140,7 @@ export class SourceWriter {
131
140
  this.declarationModules = new Map(program?.modules.flatMap((programModule) => [
132
141
  ...(programModule.records ?? []).map((declaration) => /** @type {const} */ ([/** @type {string} */ (declaration.id), programModule])),
133
142
  ...(programModule.classes ?? []).map((declaration) => /** @type {const} */ ([/** @type {string} */ (declaration.id), programModule])),
143
+ ...(programModule.interfaces ?? []).map((declaration) => /** @type {const} */ ([/** @type {string} */ (declaration.id), programModule])),
134
144
  ...(programModule.errors ?? []).map((declaration) => /** @type {const} */ ([/** @type {string} */ (declaration.id), programModule])),
135
145
  ...programModule.functions.map((declaration) => /** @type {const} */ ([/** @type {string} */ (declaration.id), programModule]))
136
146
  ]) ?? [])
@@ -282,6 +292,34 @@ export class SourceWriter {
282
292
  return declaration.name
283
293
  }
284
294
 
295
+ /**
296
+ * Resolves one validated interface declaration.
297
+ * @param {string} declarationId - Stable interface identity.
298
+ * @returns {import("../semantic/types.js").InterfaceDeclaration} Interface declaration.
299
+ */
300
+ interfaceForId(declarationId) {
301
+ const declaration = this.interfaces.get(declarationId)
302
+
303
+ if (!declaration) throw new RangeError(`Unknown validated interface identity '${declarationId}'.`)
304
+
305
+ return declaration
306
+ }
307
+
308
+ /**
309
+ * Returns the target spelling of one interface.
310
+ * @param {string} declarationId - Stable interface declaration identity.
311
+ * @returns {string} Target spelling.
312
+ */
313
+ interfaceNameForId(declarationId) {
314
+ const declaration = this.interfaceForId(declarationId)
315
+ const imported = this.#programModule()?.imports.find((item) => item.declarationId == declarationId)
316
+
317
+ if (imported && (this.language == "javascript" || this.language == "typescript" || this.language == "php")) {
318
+ return this.importNameFor(imported)
319
+ }
320
+ return declaration.name
321
+ }
322
+
285
323
  /**
286
324
  * Resolves one validated owned-resource declaration.
287
325
  * @param {string} resourceId - Stable resource identity.
@@ -318,9 +356,9 @@ export class SourceWriter {
318
356
  }
319
357
 
320
358
  /**
321
- * Resolves one validated receiver method.
359
+ * Resolves one validated receiver method, class-owned or interface-declared.
322
360
  * @param {string} methodId - Stable method identity.
323
- * @returns {import("../semantic/types.js").MethodDeclaration} Method declaration.
361
+ * @returns {import("../semantic/types.js").MethodDeclaration | import("../semantic/types.js").InterfaceMethodDeclaration} Method declaration.
324
362
  */
325
363
  methodForId(methodId) {
326
364
  const method = this.methods.get(methodId)
@@ -49,7 +49,7 @@ const referenceMethodHooks = new Set(["clone", "equals", "finalize", "getClass",
49
49
  * @property {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Errors by identity.
50
50
  * @property {Set<string>} erasedBindingNames - Source bindings consumed by exact semantic folds in this scope.
51
51
  * @property {Map<string, JavaFunctionSignature>} functions - Explicit module function signatures.
52
- * @property {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
52
+ * @property {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by source name.
53
53
  * @property {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
54
54
  * @property {import("../semantic/types.js").SemanticFunctionReturnType | undefined} returnType - Enclosing return type.
55
55
  * @property {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
@@ -260,6 +260,9 @@ function convertExpression(node, filename, source, context, expectedType) {
260
260
  kind: /** @type {const} */ ("ReferenceConstruction"), location,
261
261
  reference: referenceType(/** @type {string} */ (declaration.id), classLocation)}, {class: classLocation})
262
262
  }
263
+ if (declaration.kind == "InterfaceDeclaration") {
264
+ return unsupportedSyntax("java", "construction of an interface", nodeLocation(typeNode, filename, source))
265
+ }
263
266
  if (declaration.kind == "EffectResourceDeclaration") {
264
267
  return unsupportedSyntax("java", "owned resource construction", nodeLocation(typeNode, filename, source))
265
268
  }
@@ -1583,7 +1586,7 @@ function convertJavaOrderedMapSequence(statements, start, filename, source, cont
1583
1586
  * @param {import("../semantic/types.js").SourceLocation} location - Source location.
1584
1587
  * @param {string} filename - Source filename.
1585
1588
  * @param {string} source - Complete source.
1586
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1589
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1587
1590
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1588
1591
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
1589
1592
  */
@@ -1685,7 +1688,7 @@ function convertType(sourceType, subject, location, filename, source, recordName
1685
1688
  * @param {import("../semantic/types.js").SourceLocation} location - Owning location.
1686
1689
  * @param {string} filename - Source filename.
1687
1690
  * @param {string} source - Complete source.
1688
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1691
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1689
1692
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1690
1693
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
1691
1694
  */
@@ -1717,7 +1720,7 @@ function convertJavaTypeArgument(node, subject, location, filename, source, reco
1717
1720
  * @param {import("../semantic/types.js").SourceLocation} location - Function location.
1718
1721
  * @param {string} filename - Source filename.
1719
1722
  * @param {string} source - Complete source.
1720
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1723
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1721
1724
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1722
1725
  * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
1723
1726
  */
@@ -1773,7 +1776,7 @@ function convertJavaTypeParameters(node, ownerId, filename, source) {
1773
1776
  * @param {import("@lezer/common").SyntaxNode} node - Method declaration.
1774
1777
  * @param {string} filename - Source filename.
1775
1778
  * @param {string} source - Complete source.
1776
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
1779
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by source name.
1777
1780
  * @param {boolean} [programFunction] - Whether the canonical project profile admits explicit public or private visibility.
1778
1781
  * @param {string} [ownerId] - Stable function identity.
1779
1782
  * @param {boolean} [referenceModule] - Whether package-visible static functions are required by sibling reference classes.
@@ -1843,7 +1846,7 @@ function convertFunctionSignature(node, filename, source, recordNames, programFu
1843
1846
  * @param {import("@lezer/common").SyntaxNode} node - Method declaration.
1844
1847
  * @param {JavaFunctionSignature} signature - Preconverted function signature.
1845
1848
  * @param {Map<string, JavaFunctionSignature>} functions - Module function signatures.
1846
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
1849
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by source name.
1847
1850
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
1848
1851
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
1849
1852
  * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
@@ -1932,7 +1935,7 @@ function convertJavaError(node, declaration, filename, source, programError = fa
1932
1935
  * Reads one package-private Java reference constructor or instance-method signature.
1933
1936
  * @param {import("@lezer/common").SyntaxNode} node - Constructor or method declaration.
1934
1937
  * @param {import("../semantic/types.js").ClassDeclaration} declaration - Declaring class.
1935
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Visible nominal declarations.
1938
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} nominalNames - Visible nominal declarations.
1936
1939
  * @param {boolean} constructor - Whether this is the sole constructor.
1937
1940
  * @param {string} filename - Source filename.
1938
1941
  * @param {string} source - Complete source.
@@ -1978,7 +1981,7 @@ function convertJavaClassCallableSignature(node, declaration, nominalNames, cons
1978
1981
  * Converts the bounded final/private-field Java reference-class profile.
1979
1982
  * @param {import("@lezer/common").SyntaxNode} node - Class declaration.
1980
1983
  * @param {import("../semantic/types.js").ClassDeclaration} declaration - Predeclared class identity.
1981
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Visible nominal declarations.
1984
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} nominalNames - Visible nominal declarations.
1982
1985
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
1983
1986
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Classes by identity.
1984
1987
  * @param {Map<string, JavaFunctionSignature>} functions - Top-level signatures.
@@ -2276,7 +2279,7 @@ function convertWhile(node, filename, source, context) {
2276
2279
  * @param {string} filename - Source filename.
2277
2280
  * @param {string} source - Complete source.
2278
2281
  * @param {Map<string, JavaFunctionSignature>} functions - Module function signatures.
2279
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
2282
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by source name.
2280
2283
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
2281
2284
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
2282
2285
  * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
@@ -2442,7 +2445,7 @@ export function parseJava({capabilities = [], filename, source, program}) {
2442
2445
  kind: /** @type {const} */ ("ClassDeclaration"), location: nodeLocation(classNode, filename, source), methods: [],
2443
2446
  name: nodeText(requiredChild(classNode, "Definition", filename, source), source)
2444
2447
  }))
2445
- const recordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} */ (
2448
+ const recordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} */ (
2446
2449
  new Map(recordDeclarations.map((declaration) => /** @type {const} */ ([declaration.name, declaration]))))
2447
2450
  for (const resource of capabilities.flatMap(({resources}) => resources)) recordNames.set(resource.name, resource)
2448
2451
  for (const declaration of referenceDeclarations) recordNames.set(declaration.name, declaration)
@@ -16,7 +16,7 @@ import {documentedValueType, instantiatedRecordFieldType, iterationBindingType,
16
16
  /** @typedef {NonNullable<import("@babel/parser").ParseResult<import("@babel/types").File>["tokens"]>[number]} BabelToken */
17
17
  /** @typedef {{byStart: Map<number, BabelToken>, tokens: BabelToken[]}} BabelTokenIndex */
18
18
  /** @typedef {{name: string, nameLocation: import("../semantic/types.js").SourceLocation, parameters: import("../semantic/types.js").Parameter[], returnType: import("../semantic/types.js").SemanticFunctionReturnType, typeParameters?: import("../semantic/types.js").TypeParameter[], location: import("../semantic/types.js").SourceLocation}} JavaScriptFunctionSignature */
19
- /** @typedef {{bindings: Map<string, import("../semantic/types.js").SemanticBindingType>, catchBindingNames?: Set<string>, catchBindingNodes?: Map<string, import("../semantic/types.js").CatchBinding>, classes: Map<string, import("../semantic/types.js").ClassDeclaration>, currentClass?: import("../semantic/types.js").ClassDeclaration, errors: Map<string, import("../semantic/types.js").ErrorDeclaration>, errorNames: Map<string, import("../semantic/types.js").ErrorDeclaration>, functions: Map<string, JavaScriptFunctionSignature>, lexicalValueNames?: Set<string>, orderedMapDeclarations?: Set<object>, recordNames: Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>, records: Map<string, import("../semantic/types.js").RecordDeclaration>, returnType?: import("../semantic/types.js").SemanticFunctionReturnType, typeParameters?: Map<string, import("../semantic/types.js").TypeParameter>, valueRecordNames: Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>}} JavaScriptConversionContext */
19
+ /** @typedef {{bindings: Map<string, import("../semantic/types.js").SemanticBindingType>, catchBindingNames?: Set<string>, catchBindingNodes?: Map<string, import("../semantic/types.js").CatchBinding>, classes: Map<string, import("../semantic/types.js").ClassDeclaration>, currentClass?: import("../semantic/types.js").ClassDeclaration, errors: Map<string, import("../semantic/types.js").ErrorDeclaration>, errorNames: Map<string, import("../semantic/types.js").ErrorDeclaration>, functions: Map<string, JavaScriptFunctionSignature>, lexicalValueNames?: Set<string>, orderedMapDeclarations?: Set<object>, recordNames: Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>, records: Map<string, import("../semantic/types.js").RecordDeclaration>, returnType?: import("../semantic/types.js").SemanticFunctionReturnType, typeParameters?: Map<string, import("../semantic/types.js").TypeParameter>, valueRecordNames: Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>}} JavaScriptConversionContext */
20
20
 
21
21
  /** @type {WeakMap<object, BabelTokenIndex>} */
22
22
  const nodeTokens = new WeakMap()
@@ -875,7 +875,7 @@ function convertLocalStatement(node, language, filename, source, context) {
875
875
  * @param {string} name - Local name.
876
876
  * @param {string} filename - Source filename.
877
877
  * @param {string} source - Complete source.
878
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
878
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by source name.
879
879
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
880
880
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
881
881
  */
@@ -1393,7 +1393,7 @@ function classJsdocTypeParameters(node, ownerId, filename, source) {
1393
1393
  * @param {import("../semantic/types.js").SourceLocation} location - Source location.
1394
1394
  * @param {string} source - Complete parser input.
1395
1395
  * @param {import("../semantic/types.js").SourceLocation} [typeLocation] - Exact type token location.
1396
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1396
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1397
1397
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1398
1398
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
1399
1399
  */
@@ -1411,7 +1411,7 @@ function convertType(sourceType, language, subject, location, source, typeLocati
1411
1411
  * @param {import("../semantic/types.js").SourceLocation} location - Function location.
1412
1412
  * @param {string} source - Complete parser input.
1413
1413
  * @param {import("../semantic/types.js").SourceLocation} [typeLocation] - Exact annotation location.
1414
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1414
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1415
1415
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1416
1416
  * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
1417
1417
  */
@@ -1428,7 +1428,7 @@ function convertReturnType(sourceType, language, subject, location, source, type
1428
1428
  * @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration location.
1429
1429
  * @param {string} filename - Source filename.
1430
1430
  * @param {string} source - Complete source.
1431
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1431
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1432
1432
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1433
1433
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
1434
1434
  */
@@ -1448,7 +1448,7 @@ function convertTypeScriptType(annotation, subject, ownerLocation, filename, sou
1448
1448
  * @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration.
1449
1449
  * @param {string} filename - Source filename.
1450
1450
  * @param {string} source - Complete source.
1451
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1451
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1452
1452
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1453
1453
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic value type.
1454
1454
  */
@@ -1467,7 +1467,7 @@ function convertTypeScriptValueTypeNode(typeNode, subject, ownerLocation, filena
1467
1467
  }
1468
1468
  if (typeNode.type == "TSTypeReference" && typeNode.typeName.type == "Identifier" &&
1469
1469
  recordNames.has(typeNode.typeName.name)) {
1470
- const declaration = /** @type {import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration} */ (recordNames.get(typeNode.typeName.name))
1470
+ const declaration = /** @type {import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration} */ (recordNames.get(typeNode.typeName.name))
1471
1471
 
1472
1472
  if (declaration.kind == "EffectResourceDeclaration") {
1473
1473
  if (typeNode.typeParameters) return unsupportedSyntax("typescript", "generic owned resource type", nodeLocation(typeNode, filename, source))
@@ -1549,7 +1549,7 @@ function convertTypeScriptValueTypeNode(typeNode, subject, ownerLocation, filena
1549
1549
  * @param {import("../semantic/types.js").SourceLocation} ownerLocation - Function location.
1550
1550
  * @param {string} filename - Source filename.
1551
1551
  * @param {string} source - Complete source.
1552
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1552
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} [recordNames] - Nominal declarations by source name.
1553
1553
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1554
1554
  * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
1555
1555
  */
@@ -1596,7 +1596,7 @@ function typeScriptTypeParameters(declaration, ownerId, filename, source) {
1596
1596
  * @param {"javascript" | "typescript"} language - Frontend language.
1597
1597
  * @param {string} filename - Source filename.
1598
1598
  * @param {string} source - Complete source.
1599
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
1599
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by source name.
1600
1600
  * @param {string} ownerId - Stable function identity.
1601
1601
  * @returns {JavaScriptFunctionSignature} Semantic function signature.
1602
1602
  */
@@ -1653,7 +1653,7 @@ function convertFunctionSignature(node, language, filename, source, recordNames,
1653
1653
  * @param {import("@babel/types").FunctionDeclaration} node - Babel function.
1654
1654
  * @param {JavaScriptFunctionSignature} signature - Converted signature.
1655
1655
  * @param {Map<string, JavaScriptFunctionSignature>} functions - Module signatures.
1656
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by name.
1656
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by name.
1657
1657
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} valueRecordNames - Nominal declarations available in value positions.
1658
1658
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
1659
1659
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
@@ -1783,7 +1783,7 @@ function convertJavaScriptError(node, declaration, language, filename, source) {
1783
1783
  * Predeclares the bounded native private-field reference-class profile and all callable signatures.
1784
1784
  * @param {import("@babel/types").ClassDeclaration} node - Parser class.
1785
1785
  * @param {import("../semantic/types.js").ClassDeclaration} declaration - Predeclared class identity.
1786
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Nominal types by name.
1786
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} nominalNames - Nominal types by name.
1787
1787
  * @param {"javascript" | "typescript"} language - Source language.
1788
1788
  * @param {string} filename - Source filename.
1789
1789
  * @param {string} source - Complete source.
@@ -1874,7 +1874,7 @@ function predeclareReferenceClass(node, declaration, nominalNames, language, fil
1874
1874
  * Converts one reference class body after every class signature is complete.
1875
1875
  * @param {import("@babel/types").ClassDeclaration} node - Parser class.
1876
1876
  * @param {import("../semantic/types.js").ClassDeclaration} declaration - Complete predeclared class signature.
1877
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Nominal types by name.
1877
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} nominalNames - Nominal types by name.
1878
1878
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} valueNames - Nominal constructors by name.
1879
1879
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
1880
1880
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Classes by identity.
@@ -1916,7 +1916,7 @@ function convertReferenceClassBodies(node, declaration, nominalNames, valueNames
1916
1916
  * Reads one constructor or method signature without admitting overloads or modifiers.
1917
1917
  * @param {import("@babel/types").ClassMethod} node - Parser method.
1918
1918
  * @param {import("../semantic/types.js").ClassDeclaration} declaration - Declaring class.
1919
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Nominal types.
1919
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} nominalNames - Nominal types.
1920
1920
  * @param {"javascript" | "typescript"} language - Source language.
1921
1921
  * @param {string} filename - Source filename.
1922
1922
  * @param {string} source - Complete source.
@@ -1972,7 +1972,7 @@ function convertClassCallableSignature(node, declaration, nominalNames, language
1972
1972
  * Converts one exact TypeScript readonly constructor-parameter record profile.
1973
1973
  * @param {import("@babel/types").ClassDeclaration} node - Class declaration.
1974
1974
  * @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
1975
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - All nominal declarations by name.
1975
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - All nominal declarations by name.
1976
1976
  * @param {string} filename - Source filename.
1977
1977
  * @param {string} source - Complete source.
1978
1978
  * @returns {import("../semantic/types.js").RecordDeclaration} Semantic record declaration.
@@ -2027,7 +2027,7 @@ function convertTypeScriptRecord(node, declaration, recordNames, filename, sourc
2027
2027
  * Converts one exact JSDoc constructor/readonly-assignment/freeze record profile.
2028
2028
  * @param {import("@babel/types").ClassDeclaration} node - Class declaration.
2029
2029
  * @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
2030
- * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by name.
2030
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} recordNames - Nominal declarations by name.
2031
2031
  * @param {string} filename - Source filename.
2032
2032
  * @param {string} source - Complete source.
2033
2033
  * @returns {import("../semantic/types.js").RecordDeclaration} Semantic record declaration.
@@ -2359,7 +2359,7 @@ export function parseJavaScriptTypeScript({capabilities = [], filename, language
2359
2359
  fields: [], id: `class:${index}`, kind: /** @type {const} */ ("ClassDeclaration"),
2360
2360
  location: nodeLocation(node, filename, source), methods: [], name: node.id?.name ?? ""
2361
2361
  }))
2362
- const recordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} */ (
2362
+ const recordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration | import("../semantic/types.js").InterfaceDeclaration>} */ (
2363
2363
  new Map(program?.records ?? []))
2364
2364
  for (const resource of capabilities.flatMap(({resources}) => resources)) recordNames.set(resource.name, resource)
2365
2365
  const valueRecordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} */ (