semantifold 0.9.0 → 0.11.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 +6 -3
- package/bin/semantifold.js +6 -0
- package/build/bin/semantifold.d.ts +3 -0
- package/build/bin/semantifold.d.ts.map +1 -0
- package/build/bin/semantifold.js +5 -0
- package/build/index.d.ts +8 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +9 -1
- package/build/src/artifact-path.d.ts +16 -0
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +29 -3
- package/build/src/backends/c-check.d.ts +7 -0
- package/build/src/backends/c-check.d.ts.map +1 -0
- package/build/src/backends/c-check.js +65 -0
- package/build/src/backends/check-plan.d.ts +96 -0
- package/build/src/backends/check-plan.d.ts.map +1 -0
- package/build/src/backends/check-plan.js +135 -0
- package/build/src/backends/cpp-check.d.ts +7 -0
- package/build/src/backends/cpp-check.d.ts.map +1 -0
- package/build/src/backends/cpp-check.js +59 -0
- package/build/src/backends/csharp-check.d.ts +7 -0
- package/build/src/backends/csharp-check.d.ts.map +1 -0
- package/build/src/backends/csharp-check.js +125 -0
- package/build/src/backends/csharp.d.ts +1 -0
- package/build/src/backends/csharp.d.ts.map +1 -1
- package/build/src/backends/csharp.js +5 -4
- package/build/src/backends/dart-check.d.ts +7 -0
- package/build/src/backends/dart-check.d.ts.map +1 -0
- package/build/src/backends/dart-check.js +103 -0
- package/build/src/backends/dart.d.ts +2 -0
- package/build/src/backends/dart.d.ts.map +1 -1
- package/build/src/backends/dart.js +5 -5
- package/build/src/backends/go-check.d.ts +7 -0
- package/build/src/backends/go-check.d.ts.map +1 -0
- package/build/src/backends/go-check.js +77 -0
- package/build/src/backends/go.d.ts +1 -0
- package/build/src/backends/go.d.ts.map +1 -1
- package/build/src/backends/go.js +3 -3
- package/build/src/backends/java-check.d.ts +21 -0
- package/build/src/backends/java-check.d.ts.map +1 -0
- package/build/src/backends/java-check.js +73 -0
- package/build/src/backends/javascript-check.d.ts +7 -0
- package/build/src/backends/javascript-check.d.ts.map +1 -0
- package/build/src/backends/javascript-check.js +29 -0
- package/build/src/backends/kotlin-check.d.ts +7 -0
- package/build/src/backends/kotlin-check.d.ts.map +1 -0
- package/build/src/backends/kotlin-check.js +31 -0
- package/build/src/backends/kotlin.d.ts +1 -1
- package/build/src/backends/kotlin.js +2 -2
- package/build/src/backends/php-check.d.ts +7 -0
- package/build/src/backends/php-check.d.ts.map +1 -0
- package/build/src/backends/php-check.js +21 -0
- package/build/src/backends/program.d.ts +7 -0
- package/build/src/backends/program.d.ts.map +1 -1
- package/build/src/backends/program.js +16 -1
- package/build/src/backends/python-check.d.ts +7 -0
- package/build/src/backends/python-check.d.ts.map +1 -0
- package/build/src/backends/python-check.js +28 -0
- package/build/src/backends/ruby-check.d.ts +7 -0
- package/build/src/backends/ruby-check.d.ts.map +1 -0
- package/build/src/backends/ruby-check.js +21 -0
- package/build/src/backends/rust-check.d.ts +7 -0
- package/build/src/backends/rust-check.d.ts.map +1 -0
- package/build/src/backends/rust-check.js +65 -0
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +29 -1
- package/build/src/backends/swift-check.d.ts +7 -0
- package/build/src/backends/swift-check.d.ts.map +1 -0
- package/build/src/backends/swift-check.js +77 -0
- package/build/src/backends/typescript-check.d.ts +7 -0
- package/build/src/backends/typescript-check.d.ts.map +1 -0
- package/build/src/backends/typescript-check.js +33 -0
- package/build/src/backends/zig-check.d.ts +7 -0
- package/build/src/backends/zig-check.d.ts.map +1 -0
- package/build/src/backends/zig-check.js +70 -0
- package/build/src/diagnostic.d.ts +13 -1
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +14 -2
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +23 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +45 -4
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +54 -3
- package/build/src/frontends/program.d.ts +6 -0
- package/build/src/frontends/program.d.ts.map +1 -1
- package/build/src/frontends/program.js +9 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +55 -5
- package/build/src/language-registry.d.ts +54 -0
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +124 -10
- package/build/src/project-build.d.ts +172 -0
- package/build/src/project-build.d.ts.map +1 -0
- package/build/src/project-build.js +320 -0
- package/build/src/project-cli.d.ts +40 -0
- package/build/src/project-cli.d.ts.map +1 -0
- package/build/src/project-cli.js +145 -0
- package/build/src/project-manifest.d.ts +148 -0
- package/build/src/project-manifest.d.ts.map +1 -0
- package/build/src/project-manifest.js +432 -0
- package/build/src/project-reporter.d.ts +81 -0
- package/build/src/project-reporter.d.ts.map +1 -0
- package/build/src/project-reporter.js +293 -0
- package/build/src/project-snapshot.d.ts +129 -0
- package/build/src/project-snapshot.d.ts.map +1 -0
- package/build/src/project-snapshot.js +362 -0
- package/build/src/project-watch-reporter.d.ts +125 -0
- package/build/src/project-watch-reporter.d.ts.map +1 -0
- package/build/src/project-watch-reporter.js +280 -0
- package/build/src/project-watch.d.ts +133 -0
- package/build/src/project-watch.d.ts.map +1 -0
- package/build/src/project-watch.js +839 -0
- package/build/src/publication.d.ts +69 -5
- package/build/src/publication.d.ts.map +1 -1
- package/build/src/publication.js +246 -57
- package/build/src/semantic/effects.js +3 -1
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +11 -1
- package/build/src/semantic/types.d.ts +355 -4
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +92 -3
- package/build/src/semantic/validate.js +18 -1
- package/build/src/subprocess.d.ts +8 -0
- package/build/src/subprocess.d.ts.map +1 -1
- package/build/src/subprocess.js +50 -9
- package/build/src/target-check.d.ts +52 -0
- package/build/src/target-check.d.ts.map +1 -0
- package/build/src/target-check.js +796 -0
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +3 -3
- package/docs/adr-expression-breadth.md +186 -0
- package/docs/architecture.md +3 -1
- package/docs/c.md +4 -0
- package/docs/cpp.md +4 -0
- package/docs/dart.md +4 -0
- package/docs/generated-artifact-publication.md +11 -8
- package/docs/kotlin.md +2 -2
- package/docs/language-support.md +40 -6
- package/docs/parser-qualification.md +1 -1
- package/docs/project-build-cli.md +147 -0
- package/docs/project-watch.md +60 -0
- package/docs/rust.md +4 -0
- package/docs/swift.md +2 -0
- package/docs/testing.md +70 -3
- package/docs/watch-build-pipeline.md +39 -23
- package/docs/zig.md +2 -0
- package/examples/jsdoc-java-watch/expected-output.txt +3 -0
- package/examples/jsdoc-java-watch/semantifold.json +23 -0
- package/examples/jsdoc-java-watch/src/main.js +21 -0
- package/index.js +8 -0
- package/package.json +6 -1
- package/src/artifact-path.js +31 -2
- package/src/backends/c-check.js +80 -0
- package/src/backends/check-plan.js +147 -0
- package/src/backends/cpp-check.js +73 -0
- package/src/backends/csharp-check.js +139 -0
- package/src/backends/csharp.js +4 -3
- package/src/backends/dart-check.js +117 -0
- package/src/backends/dart.js +4 -4
- package/src/backends/go-check.js +89 -0
- package/src/backends/go.js +2 -2
- package/src/backends/java-check.js +77 -0
- package/src/backends/javascript-check.js +33 -0
- package/src/backends/kotlin-check.js +41 -0
- package/src/backends/kotlin.js +1 -1
- package/src/backends/php-check.js +23 -0
- package/src/backends/program.js +17 -0
- package/src/backends/python-check.js +30 -0
- package/src/backends/ruby-check.js +23 -0
- package/src/backends/rust-check.js +78 -0
- package/src/backends/shared.js +30 -0
- package/src/backends/swift-check.js +89 -0
- package/src/backends/typescript-check.js +37 -0
- package/src/backends/zig-check.js +81 -0
- package/src/diagnostic.js +9 -1
- package/src/frontends/java.js +24 -0
- package/src/frontends/javascript-typescript.js +49 -2
- package/src/frontends/php.js +61 -2
- package/src/frontends/program.js +9 -0
- package/src/frontends/ruby.js +62 -2
- package/src/language-registry.js +130 -9
- package/src/project-build.js +353 -0
- package/src/project-cli.js +155 -0
- package/src/project-manifest.js +479 -0
- package/src/project-reporter.js +320 -0
- package/src/project-snapshot.js +403 -0
- package/src/project-watch-reporter.js +303 -0
- package/src/project-watch.js +870 -0
- package/src/publication.js +275 -58
- package/src/semantic/effects.js +1 -0
- package/src/semantic/provenance.js +8 -0
- package/src/semantic/types.js +101 -2
- package/src/semantic/validate.js +26 -0
- package/src/subprocess.js +49 -8
- package/src/target-check.js +844 -0
- package/src/toolchains.js +3 -2
- package/tsconfig.json +1 -1
package/src/frontends/ruby.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
ConstantReadNode,
|
|
15
15
|
DefNode,
|
|
16
16
|
ElseNode,
|
|
17
|
+
EmbeddedStatementsNode,
|
|
17
18
|
FalseNode,
|
|
18
19
|
HashNode,
|
|
19
20
|
IfNode,
|
|
@@ -49,7 +50,7 @@ import {blockReferencesProtectedEntry} from "../semantic/effects.js"
|
|
|
49
50
|
import {locationFromOffsets, moduleLocation, utf8ByteOffsetToUtf16Offset} from "../semantic/location.js"
|
|
50
51
|
import {withAdaptedOperation} from "../semantic/operators.js"
|
|
51
52
|
import {withParserRanges} from "../semantic/provenance.js"
|
|
52
|
-
import {hasOnlyUnicodeScalars} from "../semantic/scalars.js"
|
|
53
|
+
import {hasOnlyUnicodeScalars, scalarType} from "../semantic/scalars.js"
|
|
53
54
|
import {isTask034ResourceProbe} from "../semantic/capabilities.js"
|
|
54
55
|
import {hasExactEffectSupport} from "../backends/effects.js"
|
|
55
56
|
import {requireSourceReturnType} from "./scalars.js"
|
|
@@ -207,7 +208,65 @@ function convertExpression(node, filename, source, context, expectedType, preser
|
|
|
207
208
|
return withParserRanges({kind: /** @type {const} */ ("StringLiteral"), location, value: decoded.value}, {literal: location})
|
|
208
209
|
}
|
|
209
210
|
|
|
210
|
-
if (node instanceof InterpolatedStringNode)
|
|
211
|
+
if (node instanceof InterpolatedStringNode) {
|
|
212
|
+
if (node.openingLoc && slicePrismSource(source, node.openingLoc.startOffset, node.openingLoc.startOffset + node.openingLoc.length).startsWith("<<")) {
|
|
213
|
+
return unsupportedSyntax("ruby", "heredoc string", location)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const parts = node.parts.map((part) => {
|
|
217
|
+
if (part instanceof StringNode) return convertExpression(part, filename, source, context, scalarType("string"))
|
|
218
|
+
if (part instanceof EmbeddedStatementsNode) {
|
|
219
|
+
const statements = part.statements
|
|
220
|
+
|
|
221
|
+
if (!statements || statements.body.length != 1) return unsupportedSyntax("ruby", "interpolated statement", nodeLocation(part, filename, source))
|
|
222
|
+
|
|
223
|
+
return convertExpression(statements.body[0], filename, source, context, scalarType("string"))
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return unsupportedSyntax("ruby", part.constructor.name, nodeLocation(part, filename, source))
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
if (parts.length == 0) return withParserRanges({kind: /** @type {const} */ ("StringLiteral"), location, value: ""}, {literal: location})
|
|
230
|
+
|
|
231
|
+
let lowered = parts[0]
|
|
232
|
+
|
|
233
|
+
for (const part of parts.slice(1)) {
|
|
234
|
+
const semantic = withAdaptedOperation({
|
|
235
|
+
kind: /** @type {const} */ ("BinaryExpression"),
|
|
236
|
+
left: lowered,
|
|
237
|
+
location,
|
|
238
|
+
right: part
|
|
239
|
+
}, /** @type {import("../semantic/operators.js").AdaptedOperation} */ ("StringConcat"))
|
|
240
|
+
|
|
241
|
+
lowered = /** @type {import("../semantic/types.js").Expression} */ (/** @type {unknown} */ (semantic))
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return withParserRanges(lowered, {literal: location})
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (node instanceof IfNode && !node.ifKeywordLoc) {
|
|
248
|
+
const elseClause = node.subsequent
|
|
249
|
+
const consequentStatements = node.statements
|
|
250
|
+
const consequentArm = consequentStatements && consequentStatements.body.length == 1 ? consequentStatements.body[0] : undefined
|
|
251
|
+
|
|
252
|
+
if (!(elseClause instanceof ElseNode) || !elseClause.statements || elseClause.statements.body.length != 1 || !consequentArm || !node.thenKeywordLoc) {
|
|
253
|
+
return unsupportedSyntax("ruby", "ternary without alternate", location)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return /** @type {import("../semantic/types.js").Expression} */ (/** @type {unknown} */ (withParserRanges({
|
|
257
|
+
alternate: convertExpression(elseClause.statements.body[0], filename, source, context),
|
|
258
|
+
condition: convertExpression(node.predicate, filename, source, context),
|
|
259
|
+
consequent: convertExpression(consequentArm, filename, source, context),
|
|
260
|
+
kind: /** @type {const} */ ("ConditionalExpression"),
|
|
261
|
+
location
|
|
262
|
+
}, {
|
|
263
|
+
alternate: nodeLocation(elseClause.statements.body[0], filename, source),
|
|
264
|
+
colon: prismLocation(elseClause.elseKeywordLoc ?? elseClause.location, filename, source),
|
|
265
|
+
condition: nodeLocation(node.predicate, filename, source),
|
|
266
|
+
consequent: nodeLocation(consequentArm, filename, source),
|
|
267
|
+
operator: prismLocation(node.thenKeywordLoc, filename, source)
|
|
268
|
+
})))
|
|
269
|
+
}
|
|
211
270
|
|
|
212
271
|
if (node instanceof OrNode && node.left instanceof LocalVariableReadNode &&
|
|
213
272
|
context.bindings.get(node.left.name)?.kind == "OptionalType") {
|
|
@@ -863,6 +922,7 @@ function convertStatement(node, comments, context, filename, source) {
|
|
|
863
922
|
if ((context.loopDepth ?? 0) > 0) return unsupportedSyntax("ruby", "nonlocal return from each block", nodeLocation(node, filename, source))
|
|
864
923
|
return convertReturn(node, filename, source, context)
|
|
865
924
|
}
|
|
925
|
+
if (node instanceof IfNode && !node.ifKeywordLoc) return unsupportedSyntax("ruby", "ternary statement", nodeLocation(node, filename, source))
|
|
866
926
|
if (node instanceof IfNode || node instanceof UnlessNode) return convertIf(node, comments, context, filename, source)
|
|
867
927
|
if (node instanceof WhileNode) return convertWhile(node, comments, context, filename, source)
|
|
868
928
|
if (node instanceof BeginNode) return convertRubyTry(node, comments, context, filename, source)
|
package/src/language-registry.js
CHANGED
|
@@ -5,6 +5,7 @@ import {SemantifoldDiagnostic, unsupportedRole} from "./diagnostic.js"
|
|
|
5
5
|
import {generateJava} from "./backends/java.js"
|
|
6
6
|
import {generateKotlin} from "./backends/kotlin.js"
|
|
7
7
|
import {generateCSharpProject} from "./backends/csharp.js"
|
|
8
|
+
import {createCSharpCheckPlan} from "./backends/csharp-check.js"
|
|
8
9
|
import {generateGoModule} from "./backends/go.js"
|
|
9
10
|
import {generateRustProject} from "./backends/rust.js"
|
|
10
11
|
import {generateSwift} from "./backends/swift.js"
|
|
@@ -35,12 +36,27 @@ import {parseJavaScriptTypeScript} from "./frontends/javascript-typescript.js"
|
|
|
35
36
|
import {parsePhp} from "./frontends/php.js"
|
|
36
37
|
import {parsePython} from "./frontends/python.js"
|
|
37
38
|
import {parseRuby} from "./frontends/ruby.js"
|
|
39
|
+
import {createJavaCheckPlan} from "./backends/java-check.js"
|
|
40
|
+
import {createJavaScriptCheckPlan} from "./backends/javascript-check.js"
|
|
41
|
+
import {createKotlinCheckPlan} from "./backends/kotlin-check.js"
|
|
42
|
+
import {createPhpCheckPlan} from "./backends/php-check.js"
|
|
43
|
+
import {createPythonCheckPlan} from "./backends/python-check.js"
|
|
44
|
+
import {createRubyCheckPlan} from "./backends/ruby-check.js"
|
|
45
|
+
import {createTypeScriptCheckPlan} from "./backends/typescript-check.js"
|
|
46
|
+
import {createGoCheckPlan} from "./backends/go-check.js"
|
|
47
|
+
import {createCCheckPlan} from "./backends/c-check.js"
|
|
48
|
+
import {createCppCheckPlan} from "./backends/cpp-check.js"
|
|
49
|
+
import {createRustCheckPlan} from "./backends/rust-check.js"
|
|
50
|
+
import {createSwiftCheckPlan} from "./backends/swift-check.js"
|
|
51
|
+
import {createDartCheckPlan} from "./backends/dart-check.js"
|
|
52
|
+
import {createZigCheckPlan} from "./backends/zig-check.js"
|
|
38
53
|
|
|
39
54
|
const registryRoles = Object.freeze(["frontend", "textBackend", "binaryBackend", "applicationBackend", "interoperability"])
|
|
40
55
|
const acceptanceStageOrder = ["parse", "generate", "restore", "compile", "link", "validate", "instantiate", "execute"]
|
|
41
56
|
const acceptanceStages = new Map(acceptanceStageOrder.map((stage, index) => [stage, index]))
|
|
57
|
+
const developerCheckStages = new Set(["restore", "compile", "link", "validate"])
|
|
42
58
|
const registryKeys = new Set([
|
|
43
|
-
"acceptance", "applicationBackend", "artifactMultiplicity", "binaryBackend", "defaultFilename", "frontend", "id",
|
|
59
|
+
"acceptance", "applicationBackend", "artifactMultiplicity", "binaryBackend", "check", "defaultFilename", "frontend", "id",
|
|
44
60
|
"features", "interoperability", "mapping", "mediaType", "provider", "roundTrip", "textBackend"
|
|
45
61
|
])
|
|
46
62
|
|
|
@@ -65,6 +81,7 @@ const registryKeys = new Set([
|
|
|
65
81
|
* @typedef LanguageRegistryRecord
|
|
66
82
|
* @property {string} id - Stable identity.
|
|
67
83
|
* @property {{stages: import("./semantic/types.js").AcceptanceStage[], toolchains: string[]}} acceptance - Acceptance declaration.
|
|
84
|
+
* @property {Readonly<LanguageRegistryCheckRecord>} check - Developer-check declaration.
|
|
68
85
|
* @property {"single" | "multiple"} artifactMultiplicity - Artifact multiplicity.
|
|
69
86
|
* @property {import("./semantic/types.js").LanguageFeatureCapabilities} features - Semantic feature capabilities.
|
|
70
87
|
* @property {import("./semantic/types.js").LanguageMappingCapabilities} mapping - Mapping capabilities.
|
|
@@ -79,6 +96,31 @@ const registryKeys = new Set([
|
|
|
79
96
|
* @property {RegistryImplementation} [interoperability] - Interoperability bridge.
|
|
80
97
|
*/
|
|
81
98
|
|
|
99
|
+
/**
|
|
100
|
+
* @typedef {Readonly<{
|
|
101
|
+
* artifacts: import("./semantic/types.js").GeneratedArtifactSet,
|
|
102
|
+
* buildPath: string,
|
|
103
|
+
* projectId: string,
|
|
104
|
+
* sourcePath: string,
|
|
105
|
+
* targetId: string,
|
|
106
|
+
* tools: readonly import("./semantic/types.js").DiscoveredToolchain[]
|
|
107
|
+
* }>} TargetCheckPlanContext
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @callback TargetCheckPlanFactory
|
|
112
|
+
* @param {TargetCheckPlanContext} context - Exact staged target context.
|
|
113
|
+
* @returns {import("./semantic/types.js").TargetCheckPlan} Immutable plan.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @typedef LanguageRegistryCheckRecord
|
|
118
|
+
* @property {TargetCheckPlanFactory} [factory] - Target-owned plan factory for supported checks.
|
|
119
|
+
* @property {readonly import("./semantic/types.js").AcceptanceStage[]} stages - Exact non-executing stages.
|
|
120
|
+
* @property {boolean} supported - Whether the target supplies a check plan.
|
|
121
|
+
* @property {readonly string[]} toolchains - Exact declared canonical toolchains.
|
|
122
|
+
*/
|
|
123
|
+
|
|
82
124
|
/**
|
|
83
125
|
* @typedef LanguageRegistry
|
|
84
126
|
* @property {readonly import("./semantic/types.js").LanguageCapabilities[]} descriptors - Public descriptors.
|
|
@@ -129,6 +171,8 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
129
171
|
const featuresCandidate = candidate.features ?? {
|
|
130
172
|
closedRecords: false,
|
|
131
173
|
conditionControlledLoops: false,
|
|
174
|
+
conditionalExpressions: false,
|
|
175
|
+
stringInterpolation: false,
|
|
132
176
|
effectfulCapabilitiesAndResources: false,
|
|
133
177
|
generalFunctionsAndCalls: false,
|
|
134
178
|
immutableCollections: false,
|
|
@@ -141,9 +185,10 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
141
185
|
}
|
|
142
186
|
|
|
143
187
|
if (!isPlainObject(featuresCandidate) ||
|
|
144
|
-
Object.keys(featuresCandidate).sort().join(",") != "closedRecords,conditionControlledLoops,effectfulCapabilitiesAndResources,generalFunctionsAndCalls,immutableCollections,optionalValues,orderedListIteration,orderedMapIteration,referenceClasses,typeParametersAndGenerics,typedErrors" ||
|
|
188
|
+
Object.keys(featuresCandidate).sort().join(",") != "closedRecords,conditionControlledLoops,conditionalExpressions,effectfulCapabilitiesAndResources,generalFunctionsAndCalls,immutableCollections,optionalValues,orderedListIteration,orderedMapIteration,referenceClasses,stringInterpolation,typeParametersAndGenerics,typedErrors" ||
|
|
145
189
|
typeof featuresCandidate.closedRecords != "boolean" ||
|
|
146
190
|
typeof featuresCandidate.conditionControlledLoops != "boolean" ||
|
|
191
|
+
typeof featuresCandidate.conditionalExpressions != "boolean" ||
|
|
147
192
|
typeof featuresCandidate.effectfulCapabilitiesAndResources != "boolean" ||
|
|
148
193
|
typeof featuresCandidate.generalFunctionsAndCalls != "boolean" ||
|
|
149
194
|
typeof featuresCandidate.immutableCollections != "boolean" ||
|
|
@@ -151,6 +196,7 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
151
196
|
typeof featuresCandidate.orderedListIteration != "boolean" ||
|
|
152
197
|
typeof featuresCandidate.orderedMapIteration != "boolean" ||
|
|
153
198
|
typeof featuresCandidate.referenceClasses != "boolean" ||
|
|
199
|
+
typeof featuresCandidate.stringInterpolation != "boolean" ||
|
|
154
200
|
typeof featuresCandidate.typedErrors != "boolean" ||
|
|
155
201
|
typeof featuresCandidate.typeParametersAndGenerics != "boolean") {
|
|
156
202
|
invalidRegistry(`Registry record '${id}' has an invalid feature declaration.`, id)
|
|
@@ -158,6 +204,7 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
158
204
|
const features = deepFreeze(/** @type {import("./semantic/types.js").LanguageFeatureCapabilities} */ ({
|
|
159
205
|
closedRecords: featuresCandidate.closedRecords,
|
|
160
206
|
conditionControlledLoops: featuresCandidate.conditionControlledLoops,
|
|
207
|
+
conditionalExpressions: featuresCandidate.conditionalExpressions,
|
|
161
208
|
effectfulCapabilitiesAndResources: featuresCandidate.effectfulCapabilitiesAndResources,
|
|
162
209
|
generalFunctionsAndCalls: featuresCandidate.generalFunctionsAndCalls,
|
|
163
210
|
immutableCollections: featuresCandidate.immutableCollections,
|
|
@@ -165,6 +212,7 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
165
212
|
orderedListIteration: featuresCandidate.orderedListIteration,
|
|
166
213
|
orderedMapIteration: featuresCandidate.orderedMapIteration,
|
|
167
214
|
referenceClasses: featuresCandidate.referenceClasses,
|
|
215
|
+
stringInterpolation: featuresCandidate.stringInterpolation,
|
|
168
216
|
typedErrors: featuresCandidate.typedErrors,
|
|
169
217
|
typeParametersAndGenerics: featuresCandidate.typeParametersAndGenerics
|
|
170
218
|
}))
|
|
@@ -218,6 +266,52 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
218
266
|
if (new Set(toolchains).size != toolchains.length) {
|
|
219
267
|
invalidRegistry(`Registry record '${id}' has duplicate acceptance toolchains.`, id)
|
|
220
268
|
}
|
|
269
|
+
const checkCandidate = candidate.check
|
|
270
|
+
/** @type {Readonly<LanguageRegistryCheckRecord>} */
|
|
271
|
+
let check
|
|
272
|
+
|
|
273
|
+
if (checkCandidate === undefined) {
|
|
274
|
+
check = deepFreeze({stages: [], supported: false, toolchains: []})
|
|
275
|
+
} else {
|
|
276
|
+
if (!isPlainObject(checkCandidate) || Object.keys(checkCandidate).sort().join(",") != "factory,stages,toolchains" ||
|
|
277
|
+
typeof checkCandidate.factory != "function" || !isDenseArray(checkCandidate.stages) ||
|
|
278
|
+
!isDenseArray(checkCandidate.toolchains) || checkCandidate.stages.length == 0) {
|
|
279
|
+
invalidRegistry(`Registry record '${id}' has an invalid developer-check declaration.`, id)
|
|
280
|
+
}
|
|
281
|
+
/** @type {unknown[]} */
|
|
282
|
+
const checkStageSnapshot = []
|
|
283
|
+
/** @type {unknown[]} */
|
|
284
|
+
const checkToolchainSnapshot = []
|
|
285
|
+
|
|
286
|
+
for (let index = 0; index < checkCandidate.stages.length; index += 1) {
|
|
287
|
+
checkStageSnapshot.push(checkCandidate.stages[index])
|
|
288
|
+
}
|
|
289
|
+
for (let index = 0; index < checkCandidate.toolchains.length; index += 1) {
|
|
290
|
+
checkToolchainSnapshot.push(checkCandidate.toolchains[index])
|
|
291
|
+
}
|
|
292
|
+
if (!checkStageSnapshot.every(stage => typeof stage == "string" && developerCheckStages.has(stage) &&
|
|
293
|
+
declaredStages.has(stage)) || !checkToolchainSnapshot.every(toolchain => typeof toolchain == "string" &&
|
|
294
|
+
toolchains.includes(toolchain)) || new Set(checkStageSnapshot).size != checkStageSnapshot.length ||
|
|
295
|
+
new Set(checkToolchainSnapshot).size != checkToolchainSnapshot.length) {
|
|
296
|
+
invalidRegistry(`Registry record '${id}' developer checks must use ordered non-executing declared stages and toolchains.`, id)
|
|
297
|
+
}
|
|
298
|
+
let previousCheckStage = -1
|
|
299
|
+
|
|
300
|
+
for (const stage of checkStageSnapshot) {
|
|
301
|
+
const stageIndex = /** @type {number} */ (acceptanceStages.get(/** @type {string} */ (stage)))
|
|
302
|
+
|
|
303
|
+
if (stageIndex < previousCheckStage) {
|
|
304
|
+
invalidRegistry(`Registry record '${id}' has unordered developer-check stages.`, id)
|
|
305
|
+
}
|
|
306
|
+
previousCheckStage = stageIndex
|
|
307
|
+
}
|
|
308
|
+
check = deepFreeze({
|
|
309
|
+
factory: /** @type {TargetCheckPlanFactory} */ (checkCandidate.factory),
|
|
310
|
+
stages: /** @type {import("./semantic/types.js").AcceptanceStage[]} */ (checkStageSnapshot),
|
|
311
|
+
supported: true,
|
|
312
|
+
toolchains: /** @type {string[]} */ (checkToolchainSnapshot)
|
|
313
|
+
})
|
|
314
|
+
}
|
|
221
315
|
|
|
222
316
|
const hasFrontend = typeof candidate.frontend == "function"
|
|
223
317
|
const hasTextBackend = typeof candidate.textBackend == "function"
|
|
@@ -225,6 +319,10 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
225
319
|
const hasApplicationBackend = typeof candidate.applicationBackend == "function"
|
|
226
320
|
const hasBackend = hasTextBackend || hasBinaryBackend || hasApplicationBackend
|
|
227
321
|
|
|
322
|
+
if (check.supported && !hasBackend) {
|
|
323
|
+
invalidRegistry(`Registry record '${id}' declares developer checks without a backend role.`, id)
|
|
324
|
+
}
|
|
325
|
+
|
|
228
326
|
if ((mapping.richText || mapping.sourceMapV3 || mapping.binaryRanges) && !hasBackend ||
|
|
229
327
|
mapping.sourceMapV3 && !mapping.richText ||
|
|
230
328
|
mapping.binaryRanges && !hasBinaryBackend && !hasApplicationBackend) {
|
|
@@ -255,6 +353,7 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
255
353
|
const record = deepFreeze(/** @type {LanguageRegistryRecord} */ ({
|
|
256
354
|
acceptance,
|
|
257
355
|
artifactMultiplicity,
|
|
356
|
+
check,
|
|
258
357
|
features,
|
|
259
358
|
id,
|
|
260
359
|
mapping,
|
|
@@ -271,6 +370,7 @@ export function createLanguageRegistry(candidateRecords) {
|
|
|
271
370
|
const descriptor = deepFreeze(/** @type {import("./semantic/types.js").LanguageCapabilities} */ ({
|
|
272
371
|
acceptance,
|
|
273
372
|
artifactMultiplicity,
|
|
373
|
+
check: deepFreeze({stages: check.stages, supported: check.supported, toolchains: check.toolchains}),
|
|
274
374
|
features,
|
|
275
375
|
id,
|
|
276
376
|
mapping,
|
|
@@ -384,7 +484,8 @@ const zigFrontend = ({filename, source}) => parseZig({filename, source})
|
|
|
384
484
|
|
|
385
485
|
const records = [
|
|
386
486
|
language({
|
|
387
|
-
acceptance: {stages: ["parse", "generate", "execute"], toolchains: ["php82"]},
|
|
487
|
+
acceptance: {stages: ["parse", "generate", "validate", "execute"], toolchains: ["php82"]},
|
|
488
|
+
check: {factory: createPhpCheckPlan, stages: ["validate"], toolchains: ["php82"]},
|
|
388
489
|
defaultFilename: "program.php",
|
|
389
490
|
frontend: phpFrontend,
|
|
390
491
|
id: "php",
|
|
@@ -392,7 +493,8 @@ const records = [
|
|
|
392
493
|
textBackend: generatePhp
|
|
393
494
|
}),
|
|
394
495
|
language({
|
|
395
|
-
acceptance: {stages: ["parse", "generate", "execute"], toolchains: ["ruby"]},
|
|
496
|
+
acceptance: {stages: ["parse", "generate", "validate", "execute"], toolchains: ["ruby"]},
|
|
497
|
+
check: {factory: createRubyCheckPlan, stages: ["validate"], toolchains: ["ruby"]},
|
|
396
498
|
defaultFilename: "program.rb",
|
|
397
499
|
frontend: rubyFrontend,
|
|
398
500
|
id: "ruby",
|
|
@@ -400,7 +502,8 @@ const records = [
|
|
|
400
502
|
textBackend: generateRuby
|
|
401
503
|
}),
|
|
402
504
|
language({
|
|
403
|
-
acceptance: {stages: ["parse", "generate", "execute"], toolchains: ["node"]},
|
|
505
|
+
acceptance: {stages: ["parse", "generate", "validate", "execute"], toolchains: ["node"]},
|
|
506
|
+
check: {factory: createJavaScriptCheckPlan, stages: ["validate"], toolchains: ["node"]},
|
|
404
507
|
defaultFilename: "program.js",
|
|
405
508
|
frontend: javaScriptFrontend,
|
|
406
509
|
id: "javascript",
|
|
@@ -409,6 +512,7 @@ const records = [
|
|
|
409
512
|
}),
|
|
410
513
|
language({
|
|
411
514
|
acceptance: {stages: ["parse", "generate", "compile", "execute"], toolchains: ["tsc", "node"]},
|
|
515
|
+
check: {factory: createTypeScriptCheckPlan, stages: ["compile"], toolchains: ["tsc"]},
|
|
412
516
|
defaultFilename: "program.ts",
|
|
413
517
|
frontend: typeScriptFrontend,
|
|
414
518
|
id: "typescript",
|
|
@@ -417,6 +521,7 @@ const records = [
|
|
|
417
521
|
}),
|
|
418
522
|
language({
|
|
419
523
|
acceptance: {stages: ["parse", "generate", "compile", "execute"], toolchains: ["javac", "java"]},
|
|
524
|
+
check: {factory: createJavaCheckPlan, stages: ["compile"], toolchains: ["javac"]},
|
|
420
525
|
defaultFilename: "Main.java",
|
|
421
526
|
frontend: javaFrontend,
|
|
422
527
|
id: "java",
|
|
@@ -425,6 +530,7 @@ const records = [
|
|
|
425
530
|
}),
|
|
426
531
|
language({
|
|
427
532
|
acceptance: {stages: ["parse", "generate", "compile", "execute"], toolchains: ["kotlinc", "java25"]},
|
|
533
|
+
check: {factory: createKotlinCheckPlan, stages: ["compile"], toolchains: ["kotlinc"]},
|
|
428
534
|
defaultFilename: "Program.kt",
|
|
429
535
|
frontend: kotlinFrontend,
|
|
430
536
|
id: "kotlin",
|
|
@@ -433,6 +539,7 @@ const records = [
|
|
|
433
539
|
}),
|
|
434
540
|
language({
|
|
435
541
|
acceptance: {stages: ["parse", "generate", "compile", "execute"], toolchains: ["python"]},
|
|
542
|
+
check: {factory: createPythonCheckPlan, stages: ["compile"], toolchains: ["python"]},
|
|
436
543
|
defaultFilename: "program.py",
|
|
437
544
|
frontend: pythonFrontend,
|
|
438
545
|
id: "python",
|
|
@@ -442,6 +549,7 @@ const records = [
|
|
|
442
549
|
language({
|
|
443
550
|
acceptance: {stages: ["parse", "generate", "restore", "compile", "execute"], toolchains: ["dotnet"]},
|
|
444
551
|
artifactMultiplicity: "multiple",
|
|
552
|
+
check: {factory: createCSharpCheckPlan, stages: ["restore", "compile"], toolchains: ["dotnet"]},
|
|
445
553
|
defaultFilename: "Program.cs",
|
|
446
554
|
frontend: csharpFrontend,
|
|
447
555
|
id: "csharp",
|
|
@@ -451,6 +559,7 @@ const records = [
|
|
|
451
559
|
language({
|
|
452
560
|
acceptance: {stages: ["parse", "generate", "compile", "validate", "execute"], toolchains: ["go"]},
|
|
453
561
|
artifactMultiplicity: "multiple",
|
|
562
|
+
check: {factory: createGoCheckPlan, stages: ["compile", "validate"], toolchains: ["go"]},
|
|
454
563
|
defaultFilename: "main.go",
|
|
455
564
|
frontend: goFrontend,
|
|
456
565
|
id: "go",
|
|
@@ -460,6 +569,7 @@ const records = [
|
|
|
460
569
|
language({
|
|
461
570
|
acceptance: {stages: ["parse", "generate", "compile", "link", "execute"], toolchains: ["clang"]},
|
|
462
571
|
artifactMultiplicity: "multiple",
|
|
572
|
+
check: {factory: createCCheckPlan, stages: ["compile", "link"], toolchains: ["clang"]},
|
|
463
573
|
defaultFilename: "program.c",
|
|
464
574
|
frontend: parseC,
|
|
465
575
|
id: "c",
|
|
@@ -468,22 +578,28 @@ const records = [
|
|
|
468
578
|
}),
|
|
469
579
|
language({
|
|
470
580
|
acceptance: {stages: ["parse", "generate", "compile", "link", "execute"], toolchains: ["clangpp"]},
|
|
581
|
+
check: {factory: createCppCheckPlan, stages: ["compile", "link"], toolchains: ["clangpp"]},
|
|
471
582
|
defaultFilename: "program.cpp", frontend: parseCpp, id: "cpp", mediaType: "text/x-c++src", textBackend: generateCpp
|
|
472
583
|
}),
|
|
473
584
|
language({
|
|
474
585
|
acceptance: {stages: ["parse", "generate", "compile", "validate", "execute"], toolchains: ["rustc", "cargo"]},
|
|
475
586
|
artifactMultiplicity: "multiple",
|
|
587
|
+
check: {factory: createRustCheckPlan, stages: ["compile", "validate"], toolchains: ["rustc", "cargo"]},
|
|
476
588
|
defaultFilename: "src/main.rs", frontend: parseRust, id: "rust", mediaType: "text/x-rust", textBackend: generateRustProject
|
|
477
589
|
}),
|
|
478
590
|
language({acceptance: {stages: ["parse", "generate", "compile", "execute"], toolchains: ["swiftc"]},
|
|
591
|
+
check: {factory: createSwiftCheckPlan, stages: ["compile"], toolchains: ["swiftc"]},
|
|
479
592
|
defaultFilename: "program.swift", frontend: parseSwift, id: "swift", mediaType: "text/x-swift", textBackend: generateSwift}),
|
|
480
593
|
language({
|
|
481
594
|
acceptance: {stages: ["parse", "generate", "restore", "compile", "validate", "execute"], toolchains: ["dart"]},
|
|
482
595
|
artifactMultiplicity: "multiple",
|
|
596
|
+
check: {factory: createDartCheckPlan, stages: ["restore", "compile", "validate"], toolchains: ["dart"]},
|
|
483
597
|
defaultFilename: "bin/program.dart",
|
|
484
598
|
features: {
|
|
485
599
|
closedRecords: false,
|
|
486
600
|
conditionControlledLoops: false,
|
|
601
|
+
conditionalExpressions: false,
|
|
602
|
+
stringInterpolation: false,
|
|
487
603
|
effectfulCapabilitiesAndResources: false,
|
|
488
604
|
generalFunctionsAndCalls: true,
|
|
489
605
|
immutableCollections: false,
|
|
@@ -502,10 +618,13 @@ const records = [
|
|
|
502
618
|
language({
|
|
503
619
|
acceptance: {stages: ["parse", "generate", "compile", "validate", "execute"], toolchains: ["zig"]},
|
|
504
620
|
artifactMultiplicity: "multiple",
|
|
621
|
+
check: {factory: createZigCheckPlan, stages: ["compile", "validate"], toolchains: ["zig"]},
|
|
505
622
|
defaultFilename: "src/main.zig",
|
|
506
623
|
features: {
|
|
507
624
|
closedRecords: false,
|
|
508
625
|
conditionControlledLoops: false,
|
|
626
|
+
conditionalExpressions: false,
|
|
627
|
+
stringInterpolation: false,
|
|
509
628
|
effectfulCapabilitiesAndResources: false,
|
|
510
629
|
generalFunctionsAndCalls: true,
|
|
511
630
|
immutableCollections: false,
|
|
@@ -527,7 +646,7 @@ const records = [
|
|
|
527
646
|
artifactMultiplicity: "multiple",
|
|
528
647
|
binaryBackend: generateBrowserWasm,
|
|
529
648
|
defaultFilename: "program.wasm",
|
|
530
|
-
features: {closedRecords: false, conditionControlledLoops: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
649
|
+
features: {closedRecords: false, conditionControlledLoops: false, conditionalExpressions: false, stringInterpolation: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
531
650
|
id: "wasm",
|
|
532
651
|
mapping: {binaryRanges: true, richText: true, sourceMapV3: true},
|
|
533
652
|
mediaType: "application/wasm",
|
|
@@ -537,7 +656,7 @@ const records = [
|
|
|
537
656
|
acceptance: {stages: ["generate", "compile", "validate", "instantiate", "execute"], toolchains: ["android"]},
|
|
538
657
|
applicationBackend: generateAndroidApplication,
|
|
539
658
|
artifactMultiplicity: "multiple",
|
|
540
|
-
features: {closedRecords: false, conditionControlledLoops: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
659
|
+
features: {closedRecords: false, conditionControlledLoops: false, conditionalExpressions: false, stringInterpolation: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
541
660
|
id: "android",
|
|
542
661
|
mapping: {binaryRanges: true, richText: true, sourceMapV3: true},
|
|
543
662
|
roundTrip: false
|
|
@@ -546,7 +665,7 @@ const records = [
|
|
|
546
665
|
acceptance: {stages: ["generate"], toolchains: []},
|
|
547
666
|
applicationBackend: generateIosApplication,
|
|
548
667
|
artifactMultiplicity: "multiple",
|
|
549
|
-
features: {closedRecords: false, conditionControlledLoops: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
668
|
+
features: {closedRecords: false, conditionControlledLoops: false, conditionalExpressions: false, stringInterpolation: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
550
669
|
id: "ios",
|
|
551
670
|
mapping: {binaryRanges: true, richText: true, sourceMapV3: true},
|
|
552
671
|
roundTrip: false
|
|
@@ -555,7 +674,7 @@ const records = [
|
|
|
555
674
|
acceptance: {stages: ["generate", "restore", "compile", "validate", "instantiate", "execute"], toolchains: ["flutter", "android"]},
|
|
556
675
|
applicationBackend: generateFlutterApplication,
|
|
557
676
|
artifactMultiplicity: "multiple",
|
|
558
|
-
features: {closedRecords: false, conditionControlledLoops: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
677
|
+
features: {closedRecords: false, conditionControlledLoops: false, conditionalExpressions: false, stringInterpolation: false, effectfulCapabilitiesAndResources: false, generalFunctionsAndCalls: false, immutableCollections: false, optionalValues: false, orderedListIteration: false, orderedMapIteration: false, referenceClasses: false, typedErrors: false, typeParametersAndGenerics: false},
|
|
559
678
|
id: "flutter",
|
|
560
679
|
mapping: {binaryRanges: true, richText: true, sourceMapV3: true},
|
|
561
680
|
roundTrip: false
|
|
@@ -580,6 +699,8 @@ function language(values) {
|
|
|
580
699
|
features: {
|
|
581
700
|
closedRecords: ["php", "ruby", "javascript", "typescript", "java"].includes(String(values.id)),
|
|
582
701
|
conditionControlledLoops: ["php", "ruby", "javascript", "typescript", "java"].includes(String(values.id)),
|
|
702
|
+
conditionalExpressions: ["php", "ruby", "javascript", "typescript", "java"].includes(String(values.id)),
|
|
703
|
+
stringInterpolation: ["php", "ruby", "javascript", "typescript"].includes(String(values.id)),
|
|
583
704
|
effectfulCapabilitiesAndResources: ["php", "ruby", "javascript", "typescript", "java"].includes(String(values.id)),
|
|
584
705
|
generalFunctionsAndCalls: ["php", "ruby", "javascript", "typescript", "java"].includes(String(values.id)),
|
|
585
706
|
immutableCollections: ["php", "ruby", "javascript", "typescript", "java"].includes(String(values.id)),
|