semantifold 0.12.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 (73) hide show
  1. package/README.md +2 -0
  2. package/build/src/backends/effects.js +5 -2
  3. package/build/src/backends/java.js +33 -14
  4. package/build/src/backends/javascript.js +83 -18
  5. package/build/src/backends/php.d.ts.map +1 -1
  6. package/build/src/backends/php.js +88 -16
  7. package/build/src/backends/ruby.js +37 -12
  8. package/build/src/backends/scalars.js +2 -2
  9. package/build/src/backends/shared.d.ts +2 -1
  10. package/build/src/backends/shared.d.ts.map +1 -1
  11. package/build/src/backends/shared.js +299 -42
  12. package/build/src/backends/typescript.js +83 -18
  13. package/build/src/backends/writer.d.ts +18 -4
  14. package/build/src/backends/writer.d.ts.map +1 -1
  15. package/build/src/backends/writer.js +40 -4
  16. package/build/src/frontends/java.d.ts +9 -1
  17. package/build/src/frontends/java.d.ts.map +1 -1
  18. package/build/src/frontends/java.js +90 -43
  19. package/build/src/frontends/javascript-typescript.d.ts +3 -1
  20. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  21. package/build/src/frontends/javascript-typescript.js +133 -52
  22. package/build/src/frontends/php.d.ts +13 -1
  23. package/build/src/frontends/php.d.ts.map +1 -1
  24. package/build/src/frontends/php.js +226 -59
  25. package/build/src/frontends/ruby.d.ts +4 -1
  26. package/build/src/frontends/ruby.d.ts.map +1 -1
  27. package/build/src/frontends/ruby.js +113 -37
  28. package/build/src/frontends/types.d.ts +9 -2
  29. package/build/src/frontends/types.d.ts.map +1 -1
  30. package/build/src/frontends/types.js +26 -9
  31. package/build/src/language-registry.d.ts.map +1 -1
  32. package/build/src/language-registry.js +14 -6
  33. package/build/src/mapping.d.ts.map +1 -1
  34. package/build/src/mapping.js +4 -2
  35. package/build/src/semantic/effects.d.ts.map +1 -1
  36. package/build/src/semantic/effects.js +20 -6
  37. package/build/src/semantic/lifetime.js +28 -4
  38. package/build/src/semantic/provenance.d.ts.map +1 -1
  39. package/build/src/semantic/provenance.js +61 -9
  40. package/build/src/semantic/types.d.ts +214 -23
  41. package/build/src/semantic/types.d.ts.map +1 -1
  42. package/build/src/semantic/types.js +58 -11
  43. package/build/src/semantic/validate.d.ts +31 -2
  44. package/build/src/semantic/validate.d.ts.map +1 -1
  45. package/build/src/semantic/validate.js +450 -60
  46. package/docs/adr/20261026-typed-error-handling-extension.md +55 -0
  47. package/docs/adr-bounded-subtyping.md +180 -0
  48. package/docs/adr-numeric-tower.md +156 -0
  49. package/docs/architecture.md +1 -1
  50. package/docs/language-support.md +8 -8
  51. package/docs/testing.md +5 -3
  52. package/package.json +1 -1
  53. package/src/backends/effects.js +3 -1
  54. package/src/backends/java.js +33 -14
  55. package/src/backends/javascript.js +83 -18
  56. package/src/backends/php.js +89 -16
  57. package/src/backends/ruby.js +36 -12
  58. package/src/backends/scalars.js +1 -1
  59. package/src/backends/shared.js +298 -47
  60. package/src/backends/typescript.js +83 -18
  61. package/src/backends/writer.js +41 -3
  62. package/src/frontends/java.js +95 -43
  63. package/src/frontends/javascript-typescript.js +145 -53
  64. package/src/frontends/php.js +243 -58
  65. package/src/frontends/ruby.js +117 -35
  66. package/src/frontends/types.js +26 -8
  67. package/src/language-registry.js +13 -5
  68. package/src/mapping.js +3 -1
  69. package/src/semantic/effects.js +18 -5
  70. package/src/semantic/lifetime.js +29 -3
  71. package/src/semantic/provenance.js +60 -14
  72. package/src/semantic/types.js +62 -10
  73. package/src/semantic/validate.js +481 -61
@@ -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)
@@ -4,7 +4,7 @@ import {parser} from "@lezer/java"
4
4
  import {SemantifoldDiagnostic, missingType, unsupportedSyntax} from "../diagnostic.js"
5
5
  import {locationFromOffsets, moduleLocation} from "../semantic/location.js"
6
6
  import {withAdaptedOperation} from "../semantic/operators.js"
7
- import {withParserRanges} from "../semantic/provenance.js"
7
+ import {setParserRanges, withParserRanges} from "../semantic/provenance.js"
8
8
  import {hasOnlyUnicodeScalars} from "../semantic/scalars.js"
9
9
  import {isTask034ResourceProbe} from "../semantic/capabilities.js"
10
10
  import {hasExactEffectSupport} from "../backends/effects.js"
@@ -41,13 +41,15 @@ const referenceMethodHooks = new Set(["clone", "equals", "finalize", "getClass",
41
41
  /**
42
42
  * @typedef JavaConversionContext
43
43
  * @property {Map<string, import("../semantic/types.js").SemanticBindingType>} bindings - Explicitly typed visible bindings.
44
+ * @property {Set<string>} [catchBindingNames] - Lexically visible exact catch binding names.
45
+ * @property {Map<string, import("../semantic/types.js").CatchBinding>} [catchBindingNodes] - Exact catch binding nodes by visible name.
44
46
  * @property {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
45
47
  * @property {import("../semantic/types.js").ClassDeclaration} [currentClass] - Enclosing reference class.
46
48
  * @property {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Errors by source name.
47
49
  * @property {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Errors by identity.
48
50
  * @property {Set<string>} erasedBindingNames - Source bindings consumed by exact semantic folds in this scope.
49
51
  * @property {Map<string, JavaFunctionSignature>} functions - Explicit module function signatures.
50
- * @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.
51
53
  * @property {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
52
54
  * @property {import("../semantic/types.js").SemanticFunctionReturnType | undefined} returnType - Enclosing return type.
53
55
  * @property {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
@@ -258,6 +260,9 @@ function convertExpression(node, filename, source, context, expectedType) {
258
260
  kind: /** @type {const} */ ("ReferenceConstruction"), location,
259
261
  reference: referenceType(/** @type {string} */ (declaration.id), classLocation)}, {class: classLocation})
260
262
  }
263
+ if (declaration.kind == "InterfaceDeclaration") {
264
+ return unsupportedSyntax("java", "construction of an interface", nodeLocation(typeNode, filename, source))
265
+ }
261
266
  if (declaration.kind == "EffectResourceDeclaration") {
262
267
  return unsupportedSyntax("java", "owned resource construction", nodeLocation(typeNode, filename, source))
263
268
  }
@@ -970,7 +975,7 @@ function convertStatement(statement, filename, source, context) {
970
975
  * @param {string} filename - Source filename.
971
976
  * @param {string} source - Complete source.
972
977
  * @param {JavaConversionContext} context - Typed lexical context.
973
- * @returns {import("../semantic/types.js").RaiseStatement} Semantic raise.
978
+ * @returns {import("../semantic/types.js").RaiseStatement | import("../semantic/types.js").RethrowStatement} Semantic raise or rethrow.
974
979
  */
975
980
  function convertJavaRaise(statement, filename, source, context) {
976
981
  const location = nodeLocation(statement, filename, source)
@@ -980,6 +985,23 @@ function convertJavaRaise(statement, filename, source, context) {
980
985
  const arguments_ = argumentsNode ? structuralChildren(argumentsNode) : []
981
986
  const declaration = typeNode ? context.errorNames.get(nodeText(typeNode, source)) : undefined
982
987
 
988
+ if (!construction && arguments_.length == 0) {
989
+ const throwNode = requiredChild(statement, "throw", filename, source)
990
+ const rethrown = structuralChildren(statement).find((candidate) => candidate.name == "Identifier")
991
+ const binding = rethrown ? context.bindings.get(nodeText(rethrown, source)) : undefined
992
+
993
+ if (rethrown && binding?.kind == "ErrorType" && context.catchBindingNames?.has(nodeText(rethrown, source))) {
994
+ const bindingNode = context.catchBindingNodes?.get(nodeText(rethrown, source))
995
+
996
+ if (!bindingNode) return unsupportedSyntax("java", "throw of a catch binding without an exact handler binding", location)
997
+ return withParserRanges({
998
+ binding: nodeText(rethrown, source),
999
+ bindingNode,
1000
+ kind: /** @type {const} */ ("RethrowStatement"),
1001
+ location
1002
+ }, {keyword: nodeLocation(throwNode, filename, source)})
1003
+ }
1004
+ }
983
1005
  if (!construction || !typeNode || !argumentsNode || !declaration || arguments_.length != 1 || construction.getChild("ClassBody")) {
984
1006
  return unsupportedSyntax("java", "throw other than exact declared error construction", location)
985
1007
  }
@@ -1009,46 +1031,76 @@ function convertJavaTry(statement, filename, source, context) {
1009
1031
  const location = nodeLocation(statement, filename, source)
1010
1032
  const body = statement.getChild("Block")
1011
1033
  const catches = statement.getChildren("CatchClause")
1034
+ const finalizer = statement.getChild("FinallyClause")
1035
+
1036
+ if (!body || (catches.length == 0 && !finalizer) || statement.getChild("ResourceSpecification")) {
1037
+ return unsupportedSyntax("java", "try without catches or finally and without resources", location)
1038
+ }
1039
+ /** @type {import("../semantic/types.js").CatchHandler[]} */
1040
+ const handlers = []
1041
+ const seenHandlerNames = new Set(context.catchBindingNames ?? [])
1042
+
1043
+ for (const handler of catches) {
1044
+ const parameter = handler.getChild("CatchFormalParameter")
1045
+ const caught = parameter?.getChild("CatchType")
1046
+ const typeNodes = caught ? structuralChildren(caught) : []
1047
+ const definition = parameter?.getChild("Definition")
1048
+ const catchBody = handler.getChild("Block")
1049
+ const typeNode = typeNodes[0]
1050
+ const declaration = typeNode ? context.errorNames.get(nodeText(typeNode, source)) : undefined
1051
+
1052
+ if (!parameter || !caught || typeNodes.length != 1 || typeNode?.name != "TypeName" || !definition || !catchBody || !declaration ||
1053
+ parameter.getChild("Modifiers")) {
1054
+ return unsupportedSyntax("java", "broad, multiple, or malformed catch", nodeLocation(handler, filename, source))
1055
+ }
1056
+ const name = nodeText(definition, source)
1012
1057
 
1013
- if (!body || catches.length != 1 || statement.getChild("FinallyClause") || statement.getChild("ResourceSpecification")) {
1014
- return unsupportedSyntax("java", "try without one catch and no resources or finally", location)
1015
- }
1016
- const handler = catches[0]
1017
- const parameter = handler.getChild("CatchFormalParameter")
1018
- const caught = parameter?.getChild("CatchType")
1019
- const typeNodes = caught ? structuralChildren(caught) : []
1020
- const definition = parameter?.getChild("Definition")
1021
- const catchBody = handler.getChild("Block")
1022
- const typeNode = typeNodes[0]
1023
- const declaration = typeNode ? context.errorNames.get(nodeText(typeNode, source)) : undefined
1024
-
1025
- if (!parameter || !caught || typeNodes.length != 1 || typeNode?.name != "TypeName" || !definition || !catchBody || !declaration ||
1026
- parameter.getChild("Modifiers")) {
1027
- return unsupportedSyntax("java", "broad, multiple, or malformed catch", nodeLocation(handler, filename, source))
1028
- }
1029
- const caughtLocation = nodeLocation(typeNode, filename, source)
1030
- const catchType = withParserRanges({declarationId: /** @type {string} */ (declaration.id), kind: /** @type {const} */ ("ErrorType")}, {
1031
- type: caughtLocation
1032
- })
1033
- const bodyContext = {...context, bindings: new Map(context.bindings), erasedBindingNames: new Set(context.erasedBindingNames)}
1034
- const catchContext = {...context, bindings: new Map(context.bindings), erasedBindingNames: new Set(context.erasedBindingNames)}
1035
- const name = nodeText(definition, source)
1058
+ if (seenHandlerNames.has(name)) {
1059
+ return unsupportedSyntax("java", `catch binding '${name}' shadows an outer handler binding`, nodeLocation(definition, filename, source))
1060
+ }
1061
+ seenHandlerNames.add(name)
1062
+ const caughtLocation = nodeLocation(typeNode, filename, source)
1063
+ const catchType = withParserRanges({declarationId: /** @type {string} */ (declaration.id), kind: /** @type {const} */ ("ErrorType")}, {
1064
+ type: caughtLocation
1065
+ })
1066
+ const catchContext = {...context, bindings: new Map(context.bindings), erasedBindingNames: new Set(context.erasedBindingNames),
1067
+ catchBindingNames: new Set(seenHandlerNames), catchBindingNodes: new Map(context.catchBindingNodes)}
1036
1068
 
1037
- catchContext.bindings.set(name, catchType)
1038
- return withParserRanges({
1039
- body: convertBlock(body, filename, source, bodyContext),
1040
- catchBinding: withParserRanges({
1069
+ catchContext.bindings.set(name, catchType)
1070
+ const catchBindingNode = withParserRanges({
1041
1071
  kind: /** @type {const} */ ("CatchBinding"),
1042
1072
  location: nodeLocation(definition, filename, source),
1043
1073
  mutable: /** @type {const} */ (false),
1044
1074
  name,
1045
1075
  type: catchType
1046
- }, {name: nodeLocation(definition, filename, source)}),
1047
- catchBody: convertBlock(catchBody, filename, source, catchContext),
1048
- catchType,
1076
+ }, {name: nodeLocation(definition, filename, source)})
1077
+
1078
+ catchContext.catchBindingNodes.set(name, catchBindingNode)
1079
+ handlers.push(withParserRanges({
1080
+ catchBinding: catchBindingNode,
1081
+ catchBody: convertBlock(catchBody, filename, source, catchContext),
1082
+ catchType,
1083
+ kind: /** @type {const} */ ("CatchHandler"),
1084
+ location: nodeLocation(handler, filename, source)
1085
+ }, {catch: nodeLocation(handler, filename, source)}))
1086
+ }
1087
+ const bodyContext = {...context, bindings: new Map(context.bindings), erasedBindingNames: new Set(context.erasedBindingNames)}
1088
+ const semantic = /** @type {import("../semantic/types.js").TryStatement} */ (withParserRanges({
1089
+ body: convertBlock(body, filename, source, bodyContext),
1090
+ handlers,
1049
1091
  kind: /** @type {const} */ ("TryStatement"),
1050
1092
  location
1051
- }, {catch: nodeLocation(handler, filename, source), try: nodeLocation(requiredChild(statement, "try", filename, source), filename, source)})
1093
+ }, {try: nodeLocation(requiredChild(statement, "try", filename, source), filename, source)}))
1094
+
1095
+ if (finalizer) {
1096
+ const finallyBlock = finalizer.getChild("Block")
1097
+
1098
+ if (!finallyBlock) return unsupportedSyntax("java", "malformed finally block", nodeLocation(finalizer, filename, source))
1099
+ semantic.finallyBody = convertBlock(finallyBlock, filename, source, bodyContext)
1100
+ setParserRanges(semantic, {finally: nodeLocation(finalizer, filename, source),
1101
+ try: nodeLocation(requiredChild(statement, "try", filename, source), filename, source)})
1102
+ }
1103
+ return semantic
1052
1104
  }
1053
1105
 
1054
1106
  /**
@@ -1534,7 +1586,7 @@ function convertJavaOrderedMapSequence(statements, start, filename, source, cont
1534
1586
  * @param {import("../semantic/types.js").SourceLocation} location - Source location.
1535
1587
  * @param {string} filename - Source filename.
1536
1588
  * @param {string} source - Complete source.
1537
- * @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.
1538
1590
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1539
1591
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
1540
1592
  */
@@ -1636,7 +1688,7 @@ function convertType(sourceType, subject, location, filename, source, recordName
1636
1688
  * @param {import("../semantic/types.js").SourceLocation} location - Owning location.
1637
1689
  * @param {string} filename - Source filename.
1638
1690
  * @param {string} source - Complete source.
1639
- * @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.
1640
1692
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1641
1693
  * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
1642
1694
  */
@@ -1668,7 +1720,7 @@ function convertJavaTypeArgument(node, subject, location, filename, source, reco
1668
1720
  * @param {import("../semantic/types.js").SourceLocation} location - Function location.
1669
1721
  * @param {string} filename - Source filename.
1670
1722
  * @param {string} source - Complete source.
1671
- * @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.
1672
1724
  * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
1673
1725
  * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
1674
1726
  */
@@ -1724,7 +1776,7 @@ function convertJavaTypeParameters(node, ownerId, filename, source) {
1724
1776
  * @param {import("@lezer/common").SyntaxNode} node - Method declaration.
1725
1777
  * @param {string} filename - Source filename.
1726
1778
  * @param {string} source - Complete source.
1727
- * @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.
1728
1780
  * @param {boolean} [programFunction] - Whether the canonical project profile admits explicit public or private visibility.
1729
1781
  * @param {string} [ownerId] - Stable function identity.
1730
1782
  * @param {boolean} [referenceModule] - Whether package-visible static functions are required by sibling reference classes.
@@ -1794,7 +1846,7 @@ function convertFunctionSignature(node, filename, source, recordNames, programFu
1794
1846
  * @param {import("@lezer/common").SyntaxNode} node - Method declaration.
1795
1847
  * @param {JavaFunctionSignature} signature - Preconverted function signature.
1796
1848
  * @param {Map<string, JavaFunctionSignature>} functions - Module function signatures.
1797
- * @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.
1798
1850
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
1799
1851
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
1800
1852
  * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
@@ -1883,7 +1935,7 @@ function convertJavaError(node, declaration, filename, source, programError = fa
1883
1935
  * Reads one package-private Java reference constructor or instance-method signature.
1884
1936
  * @param {import("@lezer/common").SyntaxNode} node - Constructor or method declaration.
1885
1937
  * @param {import("../semantic/types.js").ClassDeclaration} declaration - Declaring class.
1886
- * @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.
1887
1939
  * @param {boolean} constructor - Whether this is the sole constructor.
1888
1940
  * @param {string} filename - Source filename.
1889
1941
  * @param {string} source - Complete source.
@@ -1929,7 +1981,7 @@ function convertJavaClassCallableSignature(node, declaration, nominalNames, cons
1929
1981
  * Converts the bounded final/private-field Java reference-class profile.
1930
1982
  * @param {import("@lezer/common").SyntaxNode} node - Class declaration.
1931
1983
  * @param {import("../semantic/types.js").ClassDeclaration} declaration - Predeclared class identity.
1932
- * @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.
1933
1985
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
1934
1986
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Classes by identity.
1935
1987
  * @param {Map<string, JavaFunctionSignature>} functions - Top-level signatures.
@@ -2227,7 +2279,7 @@ function convertWhile(node, filename, source, context) {
2227
2279
  * @param {string} filename - Source filename.
2228
2280
  * @param {string} source - Complete source.
2229
2281
  * @param {Map<string, JavaFunctionSignature>} functions - Module function signatures.
2230
- * @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.
2231
2283
  * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
2232
2284
  * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
2233
2285
  * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
@@ -2393,7 +2445,7 @@ export function parseJava({capabilities = [], filename, source, program}) {
2393
2445
  kind: /** @type {const} */ ("ClassDeclaration"), location: nodeLocation(classNode, filename, source), methods: [],
2394
2446
  name: nodeText(requiredChild(classNode, "Definition", filename, source), source)
2395
2447
  }))
2396
- 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>} */ (
2397
2449
  new Map(recordDeclarations.map((declaration) => /** @type {const} */ ([declaration.name, declaration]))))
2398
2450
  for (const resource of capabilities.flatMap(({resources}) => resources)) recordNames.set(resource.name, resource)
2399
2451
  for (const declaration of referenceDeclarations) recordNames.set(declaration.name, declaration)