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.
- package/README.md +2 -0
- package/build/src/backends/effects.js +5 -2
- package/build/src/backends/java.js +33 -14
- package/build/src/backends/javascript.js +83 -18
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +88 -16
- package/build/src/backends/ruby.js +37 -12
- package/build/src/backends/scalars.js +2 -2
- package/build/src/backends/shared.d.ts +2 -1
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +299 -42
- package/build/src/backends/typescript.js +83 -18
- package/build/src/backends/writer.d.ts +18 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +40 -4
- package/build/src/frontends/java.d.ts +9 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +90 -43
- package/build/src/frontends/javascript-typescript.d.ts +3 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +133 -52
- package/build/src/frontends/php.d.ts +13 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +226 -59
- package/build/src/frontends/ruby.d.ts +4 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +113 -37
- package/build/src/frontends/types.d.ts +9 -2
- package/build/src/frontends/types.d.ts.map +1 -1
- package/build/src/frontends/types.js +26 -9
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +14 -6
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +4 -2
- package/build/src/semantic/effects.d.ts.map +1 -1
- package/build/src/semantic/effects.js +20 -6
- package/build/src/semantic/lifetime.js +28 -4
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +61 -9
- package/build/src/semantic/types.d.ts +214 -23
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +58 -11
- package/build/src/semantic/validate.d.ts +31 -2
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +450 -60
- package/docs/adr/20261026-typed-error-handling-extension.md +55 -0
- package/docs/adr-bounded-subtyping.md +180 -0
- package/docs/adr-numeric-tower.md +156 -0
- package/docs/architecture.md +1 -1
- package/docs/language-support.md +8 -8
- package/docs/testing.md +5 -3
- package/package.json +1 -1
- package/src/backends/effects.js +3 -1
- package/src/backends/java.js +33 -14
- package/src/backends/javascript.js +83 -18
- package/src/backends/php.js +89 -16
- package/src/backends/ruby.js +36 -12
- package/src/backends/scalars.js +1 -1
- package/src/backends/shared.js +298 -47
- package/src/backends/typescript.js +83 -18
- package/src/backends/writer.js +41 -3
- package/src/frontends/java.js +95 -43
- package/src/frontends/javascript-typescript.js +145 -53
- package/src/frontends/php.js +243 -58
- package/src/frontends/ruby.js +117 -35
- package/src/frontends/types.js +26 -8
- package/src/language-registry.js +13 -5
- package/src/mapping.js +3 -1
- package/src/semantic/effects.js +18 -5
- package/src/semantic/lifetime.js +29 -3
- package/src/semantic/provenance.js +60 -14
- package/src/semantic/types.js +62 -10
- package/src/semantic/validate.js +481 -61
|
@@ -6,7 +6,7 @@ import {missingType, parseFailure, SemantifoldDiagnostic, unsupportedSyntax} fro
|
|
|
6
6
|
import {blockReferencesProtectedEntry} from "../semantic/effects.js"
|
|
7
7
|
import {locationFromOffsets, moduleLocation} from "../semantic/location.js"
|
|
8
8
|
import {withAdaptedOperation} from "../semantic/operators.js"
|
|
9
|
-
import {withParserRanges} from "../semantic/provenance.js"
|
|
9
|
+
import {setParserRanges, withParserRanges} from "../semantic/provenance.js"
|
|
10
10
|
import {hasOnlyUnicodeScalars, scalarType} from "../semantic/scalars.js"
|
|
11
11
|
import {isTask034ResourceProbe} from "../semantic/capabilities.js"
|
|
12
12
|
import {hasExactEffectSupport} from "../backends/effects.js"
|
|
@@ -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>, 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
|
*/
|
|
@@ -966,12 +966,23 @@ function convertStatement(node, language, filename, source, canonicalZeroRequire
|
|
|
966
966
|
* @param {string} filename - Source filename.
|
|
967
967
|
* @param {string} source - Complete source.
|
|
968
968
|
* @param {JavaScriptConversionContext} context - Typed lexical context.
|
|
969
|
-
* @returns {import("../semantic/types.js").RaiseStatement} Semantic raise.
|
|
969
|
+
* @returns {import("../semantic/types.js").RaiseStatement | import("../semantic/types.js").RethrowStatement} Semantic raise or rethrow.
|
|
970
970
|
*/
|
|
971
971
|
function convertTypedThrow(node, language, filename, source, context) {
|
|
972
972
|
const location = nodeLocation(node, filename, source)
|
|
973
973
|
const argument = node.argument
|
|
974
974
|
|
|
975
|
+
if (argument?.type == "Identifier" && context.catchBindingNames?.has(argument.name) && context.bindings.get(argument.name)?.kind == "ErrorType") {
|
|
976
|
+
const bindingNode = context.catchBindingNodes?.get(argument.name)
|
|
977
|
+
|
|
978
|
+
if (!bindingNode) return unsupportedSyntax(language, "throw of a catch binding without an exact handler binding", location)
|
|
979
|
+
return withParserRanges({
|
|
980
|
+
binding: argument.name,
|
|
981
|
+
bindingNode,
|
|
982
|
+
kind: /** @type {const} */ ("RethrowStatement"),
|
|
983
|
+
location
|
|
984
|
+
}, {keyword: tokenLocation(node, "throw", node.start ?? 0, argument.start ?? node.end ?? source.length, filename, source)})
|
|
985
|
+
}
|
|
975
986
|
if (!argument || argument.type != "NewExpression" || argument.callee.type != "Identifier" ||
|
|
976
987
|
context.bindings.has(argument.callee.name) || !context.errorNames.has(argument.callee.name) || argument.arguments.length != 1 ||
|
|
977
988
|
argument.arguments[0].type == "SpreadElement" || argument.arguments[0].type == "ArgumentPlaceholder" ||
|
|
@@ -1006,53 +1017,134 @@ function convertTypedThrow(node, language, filename, source, context) {
|
|
|
1006
1017
|
function convertTypedTry(node, language, filename, source, canonicalZeroRequired, context) {
|
|
1007
1018
|
const location = nodeLocation(node, filename, source)
|
|
1008
1019
|
|
|
1009
|
-
if (
|
|
1010
|
-
return unsupportedSyntax(language, "try without
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
}, {type: caughtTypeLocation})
|
|
1020
|
+
if (!node.handler) {
|
|
1021
|
+
if (!node.finalizer) return unsupportedSyntax(language, "try without an explicit guarded catch", location)
|
|
1022
|
+
const bodyContext = {...context, bindings: new Map(context.bindings)}
|
|
1023
|
+
const semantic = /** @type {import("../semantic/types.js").TryStatement} */ (withParserRanges({
|
|
1024
|
+
body: convertBlock(node.block, language, filename, source, canonicalZeroRequired, bodyContext),
|
|
1025
|
+
handlers: [],
|
|
1026
|
+
kind: /** @type {const} */ ("TryStatement"),
|
|
1027
|
+
location
|
|
1028
|
+
}, {
|
|
1029
|
+
try: tokenLocation(node, "try", node.start ?? 0, node.block.start ?? node.end ?? source.length, filename, source)
|
|
1030
|
+
}))
|
|
1031
|
+
|
|
1032
|
+
semantic.finallyBody = convertBlock(node.finalizer.body, language, filename, source, canonicalZeroRequired,
|
|
1033
|
+
{...context, bindings: new Map(context.bindings)}, nodeLocation(node.finalizer, filename, source))
|
|
1034
|
+
setParserRanges(semantic, {finally: nodeLocation(node.finalizer, filename, source),
|
|
1035
|
+
try: tokenLocation(node, "try", node.start ?? 0, node.block.start ?? node.end ?? source.length, filename, source)})
|
|
1036
|
+
return semantic
|
|
1037
|
+
}
|
|
1038
|
+
/** @type {import("../semantic/types.js").CatchHandler[]} */
|
|
1039
|
+
const handlers = []
|
|
1040
|
+
const seenHandlerNames = new Set(context.catchBindingNames ?? [])
|
|
1031
1041
|
const bodyContext = {...context, bindings: new Map(context.bindings)}
|
|
1032
|
-
const catchContext = {...context, bindings: new Map(context.bindings)}
|
|
1033
1042
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1043
|
+
// JavaScript has no sibling catch clauses, so the exact native profile for ordered
|
|
1044
|
+
// multi-catch is a guarded dispatch chain: each unmatched guard rethrows into the next
|
|
1045
|
+
// clause. The chain flattens back to one ordered handler list here.
|
|
1046
|
+
/** @type {import("@babel/types").CatchClause | undefined} */
|
|
1047
|
+
let clause = node.handler
|
|
1048
|
+
|
|
1049
|
+
while (clause) {
|
|
1050
|
+
const binding = clause.param
|
|
1051
|
+
|
|
1052
|
+
if (binding?.type != "Identifier" || clause.body.directives.length > 0) {
|
|
1053
|
+
return unsupportedSyntax(language, "catch without one explicit binding", nodeLocation(clause, filename, source))
|
|
1054
|
+
}
|
|
1055
|
+
if (seenHandlerNames.has(binding.name)) {
|
|
1056
|
+
return unsupportedSyntax(language, `catch binding '${binding.name}' shadows an outer handler binding`,
|
|
1057
|
+
identifierLocation(binding, filename, source))
|
|
1058
|
+
}
|
|
1059
|
+
seenHandlerNames.add(binding.name)
|
|
1060
|
+
|
|
1061
|
+
/** @type {import("@babel/types").Statement | undefined} */
|
|
1062
|
+
const guard = clause.body.body[0]
|
|
1063
|
+
|
|
1064
|
+
if (!guard || guard.type != "IfStatement" || guard.test.type != "UnaryExpression" ||
|
|
1065
|
+
guard.test.operator != "!" || guard.test.argument.type != "BinaryExpression" || guard.test.argument.operator != "instanceof" ||
|
|
1066
|
+
guard.test.argument.left.type != "Identifier" || guard.test.argument.left.name != binding.name ||
|
|
1067
|
+
guard.test.argument.right.type != "Identifier" || guard.test.argument.right.name == binding.name ||
|
|
1068
|
+
context.bindings.has(guard.test.argument.right.name) || !context.errorNames.has(guard.test.argument.right.name) ||
|
|
1069
|
+
guard.consequent.type != "BlockStatement" || guard.consequent.body.length != 1 || guard.consequent.directives.length > 0 ||
|
|
1070
|
+
(guard.alternate && (guard.alternate.type != "BlockStatement" || guard.alternate.directives.length > 0))) {
|
|
1071
|
+
return unsupportedSyntax(language, "catch without exact instanceof guard", nodeLocation(guard ?? clause, filename, source))
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/** @type {import("@babel/types").Statement | undefined} */
|
|
1075
|
+
const dispatch = guard.consequent.body[0]
|
|
1076
|
+
/** @type {import("@babel/types").CatchClause | undefined} */
|
|
1077
|
+
let nextClause = undefined
|
|
1078
|
+
/** @type {import("@babel/types").Statement[]} */
|
|
1079
|
+
let handlerBodyStatements = clause.body.body.slice(1)
|
|
1080
|
+
let handlerBodyLocation = nodeLocation(clause.body, filename, source)
|
|
1081
|
+
|
|
1082
|
+
if (dispatch.type == "TryStatement") {
|
|
1083
|
+
if (dispatch.finalizer || !dispatch.handler || dispatch.block.body.length != 1 || dispatch.block.body[0].type != "ThrowStatement" ||
|
|
1084
|
+
dispatch.block.body[0].argument?.type != "Identifier" || dispatch.block.body[0].argument.name != binding.name ||
|
|
1085
|
+
!guard.alternate || clause.body.body.length != 1) {
|
|
1086
|
+
return unsupportedSyntax(language, "catch guard dispatch without exact rethrow of its own binding",
|
|
1087
|
+
nodeLocation(dispatch, filename, source))
|
|
1088
|
+
}
|
|
1089
|
+
nextClause = dispatch.handler
|
|
1090
|
+
handlerBodyStatements = /** @type {import("@babel/types").BlockStatement} */ (guard.alternate).body
|
|
1091
|
+
handlerBodyLocation = nodeLocation(guard.alternate, filename, source)
|
|
1092
|
+
} else if (dispatch.type != "ThrowStatement" || dispatch.argument?.type != "Identifier" || dispatch.argument.name != binding.name) {
|
|
1093
|
+
return unsupportedSyntax(language, "catch guard without exact unmatched rethrow", nodeLocation(dispatch, filename, source))
|
|
1094
|
+
} else if (guard.alternate) {
|
|
1095
|
+
if (clause.body.body.length != 1) {
|
|
1096
|
+
return unsupportedSyntax(language, "catch guard dispatch without exact rethrow of its own binding",
|
|
1097
|
+
nodeLocation(guard.alternate, filename, source))
|
|
1098
|
+
}
|
|
1099
|
+
handlerBodyStatements = /** @type {import("@babel/types").BlockStatement} */ (guard.alternate).body
|
|
1100
|
+
handlerBodyLocation = nodeLocation(guard.alternate, filename, source)
|
|
1101
|
+
}
|
|
1036
1102
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1103
|
+
const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (context.errorNames.get(guard.test.argument.right.name))
|
|
1104
|
+
const caughtTypeLocation = identifierLocation(guard.test.argument.right, filename, source)
|
|
1105
|
+
const catchType = withParserRanges({
|
|
1106
|
+
declarationId: /** @type {string} */ (declaration.id),
|
|
1107
|
+
kind: /** @type {const} */ ("ErrorType")
|
|
1108
|
+
}, {type: caughtTypeLocation})
|
|
1109
|
+
const catchContext = {...context, bindings: new Map(context.bindings), catchBindingNames: new Set(seenHandlerNames),
|
|
1110
|
+
catchBindingNodes: new Map(context.catchBindingNodes)}
|
|
1111
|
+
|
|
1112
|
+
catchContext.bindings.set(binding.name, catchType)
|
|
1113
|
+
const catchBindingNode = withParserRanges({
|
|
1040
1114
|
kind: /** @type {const} */ ("CatchBinding"),
|
|
1041
1115
|
location: identifierLocation(binding, filename, source),
|
|
1042
1116
|
mutable: /** @type {const} */ (false),
|
|
1043
1117
|
name: binding.name,
|
|
1044
1118
|
type: catchType
|
|
1045
|
-
}, {name: identifierLocation(binding, filename, source)})
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1119
|
+
}, {name: identifierLocation(binding, filename, source)})
|
|
1120
|
+
|
|
1121
|
+
catchContext.catchBindingNodes.set(binding.name, catchBindingNode)
|
|
1122
|
+
handlers.push(withParserRanges({
|
|
1123
|
+
catchBinding: catchBindingNode,
|
|
1124
|
+
catchBody: convertBlock(handlerBodyStatements, language, filename, source, canonicalZeroRequired, catchContext,
|
|
1125
|
+
handlerBodyLocation),
|
|
1126
|
+
catchType,
|
|
1127
|
+
kind: /** @type {const} */ ("CatchHandler"),
|
|
1128
|
+
location: nodeLocation(clause, filename, source)
|
|
1129
|
+
}, {catch: tokenLocation(clause, "catch", clause.start ?? 0, binding.start ?? clause.end ?? source.length, filename, source)}))
|
|
1130
|
+
clause = nextClause
|
|
1131
|
+
}
|
|
1132
|
+
const semantic = /** @type {import("../semantic/types.js").TryStatement} */ (withParserRanges({
|
|
1133
|
+
body: convertBlock(node.block, language, filename, source, canonicalZeroRequired, bodyContext),
|
|
1134
|
+
handlers,
|
|
1049
1135
|
kind: /** @type {const} */ ("TryStatement"),
|
|
1050
1136
|
location
|
|
1051
1137
|
}, {
|
|
1052
|
-
catch: tokenLocation(node.handler, "catch", node.handler.start ?? 0, binding.start ?? node.handler.end ?? source.length, filename, source),
|
|
1053
|
-
guard: nodeLocation(guard, filename, source),
|
|
1054
1138
|
try: tokenLocation(node, "try", node.start ?? 0, node.block.start ?? node.end ?? source.length, filename, source)
|
|
1055
|
-
})
|
|
1139
|
+
}))
|
|
1140
|
+
|
|
1141
|
+
if (node.finalizer) {
|
|
1142
|
+
semantic.finallyBody = convertBlock(node.finalizer.body, language, filename, source, canonicalZeroRequired,
|
|
1143
|
+
{...context, bindings: new Map(context.bindings)}, nodeLocation(node.finalizer, filename, source))
|
|
1144
|
+
setParserRanges(semantic, {finally: nodeLocation(node.finalizer, filename, source),
|
|
1145
|
+
try: tokenLocation(node, "try", node.start ?? 0, node.block.start ?? node.end ?? source.length, filename, source)})
|
|
1146
|
+
}
|
|
1147
|
+
return semantic
|
|
1056
1148
|
}
|
|
1057
1149
|
|
|
1058
1150
|
/**
|
|
@@ -1301,7 +1393,7 @@ function classJsdocTypeParameters(node, ownerId, filename, source) {
|
|
|
1301
1393
|
* @param {import("../semantic/types.js").SourceLocation} location - Source location.
|
|
1302
1394
|
* @param {string} source - Complete parser input.
|
|
1303
1395
|
* @param {import("../semantic/types.js").SourceLocation} [typeLocation] - Exact type token location.
|
|
1304
|
-
* @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.
|
|
1305
1397
|
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1306
1398
|
* @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
|
|
1307
1399
|
*/
|
|
@@ -1319,7 +1411,7 @@ function convertType(sourceType, language, subject, location, source, typeLocati
|
|
|
1319
1411
|
* @param {import("../semantic/types.js").SourceLocation} location - Function location.
|
|
1320
1412
|
* @param {string} source - Complete parser input.
|
|
1321
1413
|
* @param {import("../semantic/types.js").SourceLocation} [typeLocation] - Exact annotation location.
|
|
1322
|
-
* @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.
|
|
1323
1415
|
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1324
1416
|
* @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
|
|
1325
1417
|
*/
|
|
@@ -1336,7 +1428,7 @@ function convertReturnType(sourceType, language, subject, location, source, type
|
|
|
1336
1428
|
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration location.
|
|
1337
1429
|
* @param {string} filename - Source filename.
|
|
1338
1430
|
* @param {string} source - Complete source.
|
|
1339
|
-
* @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.
|
|
1340
1432
|
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1341
1433
|
* @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
|
|
1342
1434
|
*/
|
|
@@ -1356,7 +1448,7 @@ function convertTypeScriptType(annotation, subject, ownerLocation, filename, sou
|
|
|
1356
1448
|
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration.
|
|
1357
1449
|
* @param {string} filename - Source filename.
|
|
1358
1450
|
* @param {string} source - Complete source.
|
|
1359
|
-
* @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.
|
|
1360
1452
|
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1361
1453
|
* @returns {import("../semantic/types.js").SemanticValueType} Semantic value type.
|
|
1362
1454
|
*/
|
|
@@ -1375,7 +1467,7 @@ function convertTypeScriptValueTypeNode(typeNode, subject, ownerLocation, filena
|
|
|
1375
1467
|
}
|
|
1376
1468
|
if (typeNode.type == "TSTypeReference" && typeNode.typeName.type == "Identifier" &&
|
|
1377
1469
|
recordNames.has(typeNode.typeName.name)) {
|
|
1378
|
-
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))
|
|
1379
1471
|
|
|
1380
1472
|
if (declaration.kind == "EffectResourceDeclaration") {
|
|
1381
1473
|
if (typeNode.typeParameters) return unsupportedSyntax("typescript", "generic owned resource type", nodeLocation(typeNode, filename, source))
|
|
@@ -1457,7 +1549,7 @@ function convertTypeScriptValueTypeNode(typeNode, subject, ownerLocation, filena
|
|
|
1457
1549
|
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Function location.
|
|
1458
1550
|
* @param {string} filename - Source filename.
|
|
1459
1551
|
* @param {string} source - Complete source.
|
|
1460
|
-
* @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.
|
|
1461
1553
|
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1462
1554
|
* @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
|
|
1463
1555
|
*/
|
|
@@ -1504,7 +1596,7 @@ function typeScriptTypeParameters(declaration, ownerId, filename, source) {
|
|
|
1504
1596
|
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
1505
1597
|
* @param {string} filename - Source filename.
|
|
1506
1598
|
* @param {string} source - Complete source.
|
|
1507
|
-
* @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.
|
|
1508
1600
|
* @param {string} ownerId - Stable function identity.
|
|
1509
1601
|
* @returns {JavaScriptFunctionSignature} Semantic function signature.
|
|
1510
1602
|
*/
|
|
@@ -1561,7 +1653,7 @@ function convertFunctionSignature(node, language, filename, source, recordNames,
|
|
|
1561
1653
|
* @param {import("@babel/types").FunctionDeclaration} node - Babel function.
|
|
1562
1654
|
* @param {JavaScriptFunctionSignature} signature - Converted signature.
|
|
1563
1655
|
* @param {Map<string, JavaScriptFunctionSignature>} functions - Module signatures.
|
|
1564
|
-
* @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.
|
|
1565
1657
|
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} valueRecordNames - Nominal declarations available in value positions.
|
|
1566
1658
|
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
|
|
1567
1659
|
* @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
|
|
@@ -1691,7 +1783,7 @@ function convertJavaScriptError(node, declaration, language, filename, source) {
|
|
|
1691
1783
|
* Predeclares the bounded native private-field reference-class profile and all callable signatures.
|
|
1692
1784
|
* @param {import("@babel/types").ClassDeclaration} node - Parser class.
|
|
1693
1785
|
* @param {import("../semantic/types.js").ClassDeclaration} declaration - Predeclared class identity.
|
|
1694
|
-
* @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.
|
|
1695
1787
|
* @param {"javascript" | "typescript"} language - Source language.
|
|
1696
1788
|
* @param {string} filename - Source filename.
|
|
1697
1789
|
* @param {string} source - Complete source.
|
|
@@ -1782,7 +1874,7 @@ function predeclareReferenceClass(node, declaration, nominalNames, language, fil
|
|
|
1782
1874
|
* Converts one reference class body after every class signature is complete.
|
|
1783
1875
|
* @param {import("@babel/types").ClassDeclaration} node - Parser class.
|
|
1784
1876
|
* @param {import("../semantic/types.js").ClassDeclaration} declaration - Complete predeclared class signature.
|
|
1785
|
-
* @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.
|
|
1786
1878
|
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} valueNames - Nominal constructors by name.
|
|
1787
1879
|
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
|
|
1788
1880
|
* @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Classes by identity.
|
|
@@ -1824,7 +1916,7 @@ function convertReferenceClassBodies(node, declaration, nominalNames, valueNames
|
|
|
1824
1916
|
* Reads one constructor or method signature without admitting overloads or modifiers.
|
|
1825
1917
|
* @param {import("@babel/types").ClassMethod} node - Parser method.
|
|
1826
1918
|
* @param {import("../semantic/types.js").ClassDeclaration} declaration - Declaring class.
|
|
1827
|
-
* @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.
|
|
1828
1920
|
* @param {"javascript" | "typescript"} language - Source language.
|
|
1829
1921
|
* @param {string} filename - Source filename.
|
|
1830
1922
|
* @param {string} source - Complete source.
|
|
@@ -1880,7 +1972,7 @@ function convertClassCallableSignature(node, declaration, nominalNames, language
|
|
|
1880
1972
|
* Converts one exact TypeScript readonly constructor-parameter record profile.
|
|
1881
1973
|
* @param {import("@babel/types").ClassDeclaration} node - Class declaration.
|
|
1882
1974
|
* @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
|
|
1883
|
-
* @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.
|
|
1884
1976
|
* @param {string} filename - Source filename.
|
|
1885
1977
|
* @param {string} source - Complete source.
|
|
1886
1978
|
* @returns {import("../semantic/types.js").RecordDeclaration} Semantic record declaration.
|
|
@@ -1935,7 +2027,7 @@ function convertTypeScriptRecord(node, declaration, recordNames, filename, sourc
|
|
|
1935
2027
|
* Converts one exact JSDoc constructor/readonly-assignment/freeze record profile.
|
|
1936
2028
|
* @param {import("@babel/types").ClassDeclaration} node - Class declaration.
|
|
1937
2029
|
* @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
|
|
1938
|
-
* @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.
|
|
1939
2031
|
* @param {string} filename - Source filename.
|
|
1940
2032
|
* @param {string} source - Complete source.
|
|
1941
2033
|
* @returns {import("../semantic/types.js").RecordDeclaration} Semantic record declaration.
|
|
@@ -2267,7 +2359,7 @@ export function parseJavaScriptTypeScript({capabilities = [], filename, language
|
|
|
2267
2359
|
fields: [], id: `class:${index}`, kind: /** @type {const} */ ("ClassDeclaration"),
|
|
2268
2360
|
location: nodeLocation(node, filename, source), methods: [], name: node.id?.name ?? ""
|
|
2269
2361
|
}))
|
|
2270
|
-
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>} */ (
|
|
2271
2363
|
new Map(program?.records ?? []))
|
|
2272
2364
|
for (const resource of capabilities.flatMap(({resources}) => resources)) recordNames.set(resource.name, resource)
|
|
2273
2365
|
const valueRecordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} */ (
|