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
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {createHash} from "node:crypto"
|
|
4
|
+
import path from "node:path"
|
|
5
|
+
import {SemantifoldDiagnostic} from "../diagnostic.js"
|
|
6
|
+
import {
|
|
7
|
+
checkArtifacts,
|
|
8
|
+
checkOutput,
|
|
9
|
+
checkPlan,
|
|
10
|
+
checkStage,
|
|
11
|
+
checkTool,
|
|
12
|
+
environmentPath,
|
|
13
|
+
pathArgument
|
|
14
|
+
} from "./check-plan.js"
|
|
15
|
+
import {csharpProjectManifest} from "./csharp.js"
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Constructs C#'s offline restore and non-executing build plan.
|
|
19
|
+
* @param {import("../language-registry.js").TargetCheckPlanContext} context - Validated candidate context.
|
|
20
|
+
* @returns {import("../semantic/types.js").TargetCheckPlan} Immutable C# plan.
|
|
21
|
+
*/
|
|
22
|
+
export function createCSharpCheckPlan(context) {
|
|
23
|
+
const tool = checkTool(context, "dotnet", "csharp")
|
|
24
|
+
const artifacts = checkArtifacts(context, artifact => artifact.path.endsWith(".cs") ||
|
|
25
|
+
artifact.path == "Semantifold.csproj" || artifact.path == "packages.lock.json",
|
|
26
|
+
"csharp", "only staged C# source and canonical project/lock artifacts")
|
|
27
|
+
const projects = context.artifacts.artifacts.filter(artifact => artifact.path == "Semantifold.csproj")
|
|
28
|
+
const sources = artifacts.filter(artifact => artifact.endsWith(".cs"))
|
|
29
|
+
|
|
30
|
+
if (projects.length != 1 || projects[0].contentKind != "text" || projects[0].role != "manifest" ||
|
|
31
|
+
projects[0].content != csharpProjectManifest) {
|
|
32
|
+
throw new SemantifoldDiagnostic({
|
|
33
|
+
code: "INVALID_TARGET_CHECK_PLAN",
|
|
34
|
+
language: "csharp",
|
|
35
|
+
message: "C# developer checks require the exact producer-owned 'Semantifold.csproj' artifact."
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
if (sources.length == 0) {
|
|
39
|
+
throw new SemantifoldDiagnostic({
|
|
40
|
+
code: "INVALID_TARGET_CHECK_PLAN",
|
|
41
|
+
language: "csharp",
|
|
42
|
+
message: "C# developer checks require at least one staged '.cs' artifact."
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
const restoreArtifacts = context.artifacts.artifacts
|
|
46
|
+
.filter(artifact => artifact.path == "Semantifold.csproj" || artifact.path == "packages.lock.json")
|
|
47
|
+
.sort((left, right) => left.path.localeCompare(right.path, "en"))
|
|
48
|
+
const restoreInputs = Object.freeze(restoreArtifacts.map(artifact => path.join(context.sourcePath, artifact.path)))
|
|
49
|
+
const restoreHash = createHash("sha256")
|
|
50
|
+
|
|
51
|
+
for (const artifact of restoreArtifacts) {
|
|
52
|
+
const contentLength = typeof artifact.content == "string" ? Buffer.byteLength(artifact.content) : artifact.content.byteLength
|
|
53
|
+
|
|
54
|
+
restoreHash.update(`${Buffer.byteLength(artifact.path)}:`).update(artifact.path)
|
|
55
|
+
.update(`${contentLength}:`).update(artifact.content)
|
|
56
|
+
}
|
|
57
|
+
const inputHash = restoreHash.digest("hex")
|
|
58
|
+
const projectPath = path.join(context.sourcePath, projects[0].path)
|
|
59
|
+
const packages = path.join(context.buildPath, "nuget-packages")
|
|
60
|
+
const intermediatePath = path.join(context.buildPath, "obj")
|
|
61
|
+
const intermediate = `${intermediatePath}/`
|
|
62
|
+
const output = path.join(context.buildPath, "bin")
|
|
63
|
+
const compileItems = sources.map(source => path.relative(context.sourcePath, source).split(path.sep).join("/")).join("%3B")
|
|
64
|
+
const isolatedProjectProperties = [
|
|
65
|
+
"--property:ImportDirectoryBuildProps=false",
|
|
66
|
+
"--property:ImportDirectoryBuildTargets=false"
|
|
67
|
+
]
|
|
68
|
+
const restoreArgv = [
|
|
69
|
+
"restore", projectPath, "--source", context.sourcePath, "--packages", packages, "--no-cache", "--force",
|
|
70
|
+
"--disable-parallel",
|
|
71
|
+
...(restoreArtifacts.some(artifact => artifact.path == "packages.lock.json") ? ["--locked-mode"] : []),
|
|
72
|
+
"--nologo", ...isolatedProjectProperties, `--property:BaseIntermediateOutputPath=${intermediate}`,
|
|
73
|
+
`--property:MSBuildProjectExtensionsPath=${intermediate}`
|
|
74
|
+
]
|
|
75
|
+
const compileArgv = [
|
|
76
|
+
"build", projectPath, "--configuration", "Release", "--no-restore", "--nologo", "--warnaserror",
|
|
77
|
+
"--disable-build-servers", "--output", output, ...isolatedProjectProperties,
|
|
78
|
+
`--property:SemantifoldCompileItems=${compileItems}`, "--property:UseSharedCompilation=false",
|
|
79
|
+
`--property:BaseIntermediateOutputPath=${intermediate}`,
|
|
80
|
+
`--property:MSBuildProjectExtensionsPath=${intermediate}`
|
|
81
|
+
]
|
|
82
|
+
const environment = {
|
|
83
|
+
DOTNET_CLI_HOME: path.join(context.buildPath, "dotnet-home"),
|
|
84
|
+
DOTNET_CLI_TELEMETRY_OPTOUT: "1",
|
|
85
|
+
DOTNET_CLI_USE_MSBUILD_SERVER: "0",
|
|
86
|
+
DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE: "1",
|
|
87
|
+
DOTNET_NOLOGO: "1",
|
|
88
|
+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1",
|
|
89
|
+
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1",
|
|
90
|
+
HOME: path.join(context.buildPath, "home"),
|
|
91
|
+
NUGET_HTTP_CACHE_PATH: path.join(context.buildPath, "nuget-http-cache"),
|
|
92
|
+
NUGET_PACKAGES: packages,
|
|
93
|
+
NUGET_PLUGINS_CACHE_PATH: path.join(context.buildPath, "nuget-plugins-cache"),
|
|
94
|
+
TMPDIR: path.join(context.buildPath, "tmp"),
|
|
95
|
+
XDG_CACHE_HOME: path.join(context.buildPath, "cache")
|
|
96
|
+
}
|
|
97
|
+
const environmentPaths = [
|
|
98
|
+
environmentPath("DOTNET_CLI_HOME", "build"), environmentPath("HOME", "build"),
|
|
99
|
+
environmentPath("NUGET_HTTP_CACHE_PATH", "build"), environmentPath("NUGET_PACKAGES", "build"),
|
|
100
|
+
environmentPath("NUGET_PLUGINS_CACHE_PATH", "build"), environmentPath("TMPDIR", "build"),
|
|
101
|
+
environmentPath("XDG_CACHE_HOME", "build")
|
|
102
|
+
]
|
|
103
|
+
const ownedOutput = checkOutput(context.buildPath, "application/octet-stream", "compiler-output")
|
|
104
|
+
const restore = checkStage({
|
|
105
|
+
argv: restoreArgv,
|
|
106
|
+
cwd: context.sourcePath,
|
|
107
|
+
environment,
|
|
108
|
+
environmentPaths,
|
|
109
|
+
inputHash,
|
|
110
|
+
inputs: restoreInputs,
|
|
111
|
+
output: null,
|
|
112
|
+
pathArguments: [
|
|
113
|
+
pathArgument(1, "source"), pathArgument(3, "source"), pathArgument(5, "build"),
|
|
114
|
+
pathArgument(restoreArgv.length - 2, "build", "--property:BaseIntermediateOutputPath="),
|
|
115
|
+
pathArgument(restoreArgv.length - 1, "build", "--property:MSBuildProjectExtensionsPath=")
|
|
116
|
+
],
|
|
117
|
+
stage: "restore",
|
|
118
|
+
tool,
|
|
119
|
+
transientPaths: [intermediatePath]
|
|
120
|
+
})
|
|
121
|
+
const compile = checkStage({
|
|
122
|
+
argv: compileArgv,
|
|
123
|
+
cwd: context.sourcePath,
|
|
124
|
+
environment,
|
|
125
|
+
environmentPaths,
|
|
126
|
+
inputs: artifacts,
|
|
127
|
+
output: ownedOutput,
|
|
128
|
+
pathArguments: [
|
|
129
|
+
pathArgument(1, "source"), pathArgument(9, "build"),
|
|
130
|
+
pathArgument(compileArgv.length - 2, "build", "--property:BaseIntermediateOutputPath="),
|
|
131
|
+
pathArgument(compileArgv.length - 1, "build", "--property:MSBuildProjectExtensionsPath=")
|
|
132
|
+
],
|
|
133
|
+
stage: "compile",
|
|
134
|
+
tool,
|
|
135
|
+
transientPaths: [intermediatePath]
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
return checkPlan(context, "csharp", artifacts, [restore, compile])
|
|
139
|
+
}
|
package/src/backends/csharp.js
CHANGED
|
@@ -6,7 +6,7 @@ import {validateBackendModule, emitExpression} from "./shared.js"
|
|
|
6
6
|
import {emitScalarType} from "./scalars.js"
|
|
7
7
|
import {SourceWriter} from "./writer.js"
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
export const csharpProjectManifest = `<Project Sdk="Microsoft.NET.Sdk">
|
|
10
10
|
<PropertyGroup>
|
|
11
11
|
<OutputType>Exe</OutputType>
|
|
12
12
|
<TargetFramework>net10.0</TargetFramework>
|
|
@@ -25,13 +25,14 @@ const project = `<Project Sdk="Microsoft.NET.Sdk">
|
|
|
25
25
|
<DebugType>none</DebugType>
|
|
26
26
|
<UseAppHost>false</UseAppHost>
|
|
27
27
|
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
|
28
|
+
<SemantifoldCompileItems Condition="'$(SemantifoldCompileItems)' == ''">Program.cs</SemantifoldCompileItems>
|
|
28
29
|
<AssemblyName>Semantifold</AssemblyName>
|
|
29
30
|
<RootNamespace>Semantifold.Generated</RootNamespace>
|
|
30
31
|
<StartupObject>Semantifold.Generated.Program</StartupObject>
|
|
31
32
|
<PathMap>$(MSBuildProjectDirectory)=/_/</PathMap>
|
|
32
33
|
</PropertyGroup>
|
|
33
34
|
<ItemGroup>
|
|
34
|
-
<Compile Include="
|
|
35
|
+
<Compile Include="$(SemantifoldCompileItems)" />
|
|
35
36
|
</ItemGroup>
|
|
36
37
|
</Project>
|
|
37
38
|
`
|
|
@@ -66,7 +67,7 @@ export function generateCSharpProject({filename, mapDirective, module, sourceMap
|
|
|
66
67
|
provenance: {kind: "text", mapping, sourceMap: toSourceMapV3(mapping)},
|
|
67
68
|
role: "entry"
|
|
68
69
|
}, {
|
|
69
|
-
content:
|
|
70
|
+
content: csharpProjectManifest,
|
|
70
71
|
contentKind: "text",
|
|
71
72
|
mediaType: "application/xml",
|
|
72
73
|
ownership: "generated",
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {createHash} from "node:crypto"
|
|
4
|
+
import path from "node:path"
|
|
5
|
+
import {SemantifoldDiagnostic} from "../diagnostic.js"
|
|
6
|
+
import {
|
|
7
|
+
checkArtifacts,
|
|
8
|
+
checkPlan,
|
|
9
|
+
checkStage,
|
|
10
|
+
checkTool,
|
|
11
|
+
environmentPath,
|
|
12
|
+
pathArgument
|
|
13
|
+
} from "./check-plan.js"
|
|
14
|
+
import {dartLockfile, dartPubspec} from "./dart.js"
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Constructs Dart's offline package verification, native compile, format and analysis plan.
|
|
18
|
+
* @param {import("../language-registry.js").TargetCheckPlanContext} context - Validated candidate context.
|
|
19
|
+
* @returns {import("../semantic/types.js").TargetCheckPlan} Immutable Dart plan.
|
|
20
|
+
*/
|
|
21
|
+
export function createDartCheckPlan(context) {
|
|
22
|
+
const tool = checkTool(context, "dart", "dart")
|
|
23
|
+
const artifacts = checkArtifacts(context, artifact => artifact.path.endsWith(".dart") ||
|
|
24
|
+
artifact.path == "pubspec.yaml" || artifact.path == "pubspec.lock",
|
|
25
|
+
"dart", "only staged Dart source and canonical pub package/lock artifacts")
|
|
26
|
+
const pubspecs = context.artifacts.artifacts.filter(artifact => artifact.path == "pubspec.yaml")
|
|
27
|
+
const lockfiles = context.artifacts.artifacts.filter(artifact => artifact.path == "pubspec.lock")
|
|
28
|
+
const sources = artifacts.filter(artifact => artifact.endsWith(".dart"))
|
|
29
|
+
|
|
30
|
+
if (pubspecs.length != 1 || pubspecs[0].contentKind != "text" || pubspecs[0].role != "manifest" ||
|
|
31
|
+
pubspecs[0].content != dartPubspec || lockfiles.length != 1 || lockfiles[0].contentKind != "text" ||
|
|
32
|
+
lockfiles[0].role != "manifest" || lockfiles[0].content != dartLockfile || artifacts.length != 3 || sources.length != 1 ||
|
|
33
|
+
sources[0] != path.join(context.sourcePath, "bin/program.dart")) {
|
|
34
|
+
throw new SemantifoldDiagnostic({
|
|
35
|
+
code: "INVALID_TARGET_CHECK_PLAN",
|
|
36
|
+
language: "dart",
|
|
37
|
+
message: "Dart developer checks require the exact dependency-free pub package/lock and staged '.dart' source."
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
const restoreArtifacts = context.artifacts.artifacts.filter(artifact =>
|
|
41
|
+
artifact.path == "pubspec.yaml" || artifact.path == "pubspec.lock").sort((left, right) => left.path.localeCompare(right.path, "en"))
|
|
42
|
+
const restoreInputs = Object.freeze(restoreArtifacts.map(artifact => path.join(context.sourcePath, artifact.path)))
|
|
43
|
+
const restoreHash = createHash("sha256")
|
|
44
|
+
|
|
45
|
+
for (const artifact of restoreArtifacts) {
|
|
46
|
+
const contentLength = typeof artifact.content == "string" ? Buffer.byteLength(artifact.content) : artifact.content.byteLength
|
|
47
|
+
|
|
48
|
+
restoreHash.update(`${Buffer.byteLength(artifact.path)}:`).update(artifact.path)
|
|
49
|
+
.update(`${contentLength}:`).update(artifact.content)
|
|
50
|
+
}
|
|
51
|
+
const home = path.join(context.buildPath, "home")
|
|
52
|
+
const pubCache = path.join(context.buildPath, "pub-cache")
|
|
53
|
+
const temporary = path.join(context.buildPath, "tmp")
|
|
54
|
+
const environment = {
|
|
55
|
+
CI: "true",
|
|
56
|
+
DART_SUPPRESS_ANALYTICS: "true",
|
|
57
|
+
HOME: home,
|
|
58
|
+
PUB_CACHE: pubCache,
|
|
59
|
+
PUB_HOSTED_URL: "http://127.0.0.1:9",
|
|
60
|
+
TMPDIR: temporary
|
|
61
|
+
}
|
|
62
|
+
const environmentPaths = [environmentPath("HOME", "build"), environmentPath("PUB_CACHE", "build"),
|
|
63
|
+
environmentPath("TMPDIR", "build")]
|
|
64
|
+
const nativeOutput = path.join(context.buildPath, "native-output")
|
|
65
|
+
const binary = path.join(nativeOutput, "semantifold-dart")
|
|
66
|
+
const compileArgv = ["compile", "exe", sources[0], "-o", binary]
|
|
67
|
+
|
|
68
|
+
return checkPlan(context, "dart", artifacts, [
|
|
69
|
+
checkStage({
|
|
70
|
+
argv: ["pub", "get", "--offline", "--dry-run", "--enforce-lockfile", "--no-precompile"],
|
|
71
|
+
cwd: context.sourcePath,
|
|
72
|
+
environment,
|
|
73
|
+
environmentPaths,
|
|
74
|
+
inputHash: restoreHash.digest("hex"),
|
|
75
|
+
inputs: restoreInputs,
|
|
76
|
+
output: null,
|
|
77
|
+
pathArguments: [],
|
|
78
|
+
stage: "restore",
|
|
79
|
+
tool,
|
|
80
|
+
transientPaths: [path.join(context.sourcePath, ".dart_tool")]
|
|
81
|
+
}),
|
|
82
|
+
checkStage({
|
|
83
|
+
argv: compileArgv,
|
|
84
|
+
cwd: context.sourcePath,
|
|
85
|
+
environment,
|
|
86
|
+
environmentPaths,
|
|
87
|
+
inputs: artifacts,
|
|
88
|
+
output: null,
|
|
89
|
+
pathArguments: [pathArgument(2, "source"), pathArgument(4, "build")],
|
|
90
|
+
stage: "compile",
|
|
91
|
+
tool,
|
|
92
|
+
transientPaths: [nativeOutput]
|
|
93
|
+
}),
|
|
94
|
+
checkStage({
|
|
95
|
+
argv: ["format", "--output=none", "--set-exit-if-changed", sources[0]],
|
|
96
|
+
cwd: context.sourcePath,
|
|
97
|
+
environment,
|
|
98
|
+
environmentPaths,
|
|
99
|
+
inputs: sources,
|
|
100
|
+
output: null,
|
|
101
|
+
pathArguments: [pathArgument(3, "source")],
|
|
102
|
+
stage: "validate",
|
|
103
|
+
tool
|
|
104
|
+
}),
|
|
105
|
+
checkStage({
|
|
106
|
+
argv: ["analyze", "--fatal-infos", "--fatal-warnings", context.sourcePath],
|
|
107
|
+
cwd: context.sourcePath,
|
|
108
|
+
environment,
|
|
109
|
+
environmentPaths,
|
|
110
|
+
inputs: artifacts,
|
|
111
|
+
output: null,
|
|
112
|
+
pathArguments: [pathArgument(3, "source")],
|
|
113
|
+
stage: "validate",
|
|
114
|
+
tool
|
|
115
|
+
})
|
|
116
|
+
])
|
|
117
|
+
}
|
package/src/backends/dart.js
CHANGED
|
@@ -7,8 +7,8 @@ import {dartRuntime} from "./dart-runtime.js"
|
|
|
7
7
|
import {emitScalarType} from "./scalars.js"
|
|
8
8
|
import {SourceWriter} from "./writer.js"
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
const
|
|
10
|
+
export const dartPubspec = "name: semantifold_generated\npublish_to: none\nenvironment:\n sdk: 3.13.3\n"
|
|
11
|
+
export const dartLockfile = "# Generated by pub\n# See https://dart.dev/tools/pub/glossary#lockfile\npackages: {}\nsdks:\n dart: \"3.13.3\"\n"
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Emits one deterministic dependency-free Dart package candidate.
|
|
@@ -35,7 +35,7 @@ export function generateDartPackage({filename, mapDirective, module, sourceMapFi
|
|
|
35
35
|
|
|
36
36
|
return {
|
|
37
37
|
artifacts: [{
|
|
38
|
-
content:
|
|
38
|
+
content: dartPubspec,
|
|
39
39
|
contentKind: "text",
|
|
40
40
|
mediaType: "application/yaml",
|
|
41
41
|
ownership: "generated",
|
|
@@ -47,7 +47,7 @@ export function generateDartPackage({filename, mapDirective, module, sourceMapFi
|
|
|
47
47
|
},
|
|
48
48
|
role: "manifest"
|
|
49
49
|
}, {
|
|
50
|
-
content:
|
|
50
|
+
content: dartLockfile,
|
|
51
51
|
contentKind: "text",
|
|
52
52
|
mediaType: "application/yaml",
|
|
53
53
|
ownership: "generated",
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
import {SemantifoldDiagnostic} from "../diagnostic.js"
|
|
5
|
+
import {
|
|
6
|
+
checkArtifacts,
|
|
7
|
+
checkOutput,
|
|
8
|
+
checkPlan,
|
|
9
|
+
checkStage,
|
|
10
|
+
checkTool,
|
|
11
|
+
environmentPath,
|
|
12
|
+
pathArgument
|
|
13
|
+
} from "./check-plan.js"
|
|
14
|
+
import {goModuleManifest} from "./go.js"
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Constructs Go's cgo-disabled, offline build/vet plan.
|
|
18
|
+
* @param {import("../language-registry.js").TargetCheckPlanContext} context - Validated candidate context.
|
|
19
|
+
* @returns {import("../semantic/types.js").TargetCheckPlan} Immutable Go plan.
|
|
20
|
+
*/
|
|
21
|
+
export function createGoCheckPlan(context) {
|
|
22
|
+
const tool = checkTool(context, "go", "go")
|
|
23
|
+
const artifacts = checkArtifacts(context, artifact => artifact.path.endsWith(".go") || artifact.path == "go.mod",
|
|
24
|
+
"go", "only staged '.go' sources and the canonical module manifest")
|
|
25
|
+
const manifests = context.artifacts.artifacts.filter(artifact => artifact.path == "go.mod")
|
|
26
|
+
const sources = artifacts.filter(artifact => artifact.endsWith(".go"))
|
|
27
|
+
|
|
28
|
+
if (manifests.length != 1 || manifests[0].contentKind != "text" || manifests[0].role != "manifest" ||
|
|
29
|
+
manifests[0].content != goModuleManifest || artifacts.length != 2 || sources.length != 1 ||
|
|
30
|
+
sources[0] != path.join(context.sourcePath, "main.go")) {
|
|
31
|
+
throw new SemantifoldDiagnostic({
|
|
32
|
+
code: "INVALID_TARGET_CHECK_PLAN",
|
|
33
|
+
language: "go",
|
|
34
|
+
message: "Go developer checks require the exact dependency-free 'go.mod' and at least one staged '.go' source."
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
const cache = path.join(context.buildPath, "go-cache")
|
|
38
|
+
const moduleCache = path.join(context.buildPath, "go-mod-cache")
|
|
39
|
+
const goPath = path.join(context.buildPath, "go-path")
|
|
40
|
+
const temporary = path.join(context.buildPath, "go-tmp")
|
|
41
|
+
const home = path.join(context.buildPath, "go-home")
|
|
42
|
+
const binary = path.join(context.buildPath, "semantifold-go")
|
|
43
|
+
const environment = {
|
|
44
|
+
CGO_ENABLED: "0",
|
|
45
|
+
GOARCH: "amd64",
|
|
46
|
+
GOCACHE: cache,
|
|
47
|
+
GOENV: "off",
|
|
48
|
+
GOMODCACHE: moduleCache,
|
|
49
|
+
GOOS: "linux",
|
|
50
|
+
GOPATH: goPath,
|
|
51
|
+
GOPROXY: "off",
|
|
52
|
+
GOSUMDB: "off",
|
|
53
|
+
GOTOOLCHAIN: "local",
|
|
54
|
+
GOTMPDIR: temporary,
|
|
55
|
+
GOVCS: "off",
|
|
56
|
+
GOWORK: "off",
|
|
57
|
+
GO_TELEMETRY_CHILD: "2",
|
|
58
|
+
HOME: home
|
|
59
|
+
}
|
|
60
|
+
const environmentPaths = [
|
|
61
|
+
environmentPath("GOCACHE", "build"), environmentPath("GOMODCACHE", "build"), environmentPath("GOPATH", "build"),
|
|
62
|
+
environmentPath("GOTMPDIR", "build"), environmentPath("HOME", "build")
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
return checkPlan(context, "go", artifacts, [
|
|
66
|
+
checkStage({
|
|
67
|
+
argv: ["build", "-mod=readonly", "-trimpath", "-buildvcs=false", "-ldflags=-buildid=", "-o", binary, "."],
|
|
68
|
+
cwd: context.sourcePath,
|
|
69
|
+
environment,
|
|
70
|
+
environmentPaths,
|
|
71
|
+
inputs: artifacts,
|
|
72
|
+
output: checkOutput(context.buildPath, "application/x-executable", "compiler-output"),
|
|
73
|
+
pathArguments: [pathArgument(6, "build")],
|
|
74
|
+
stage: "compile",
|
|
75
|
+
tool
|
|
76
|
+
}),
|
|
77
|
+
checkStage({
|
|
78
|
+
argv: ["vet", "-mod=readonly", "."],
|
|
79
|
+
cwd: context.sourcePath,
|
|
80
|
+
environment,
|
|
81
|
+
environmentPaths,
|
|
82
|
+
inputs: artifacts,
|
|
83
|
+
output: null,
|
|
84
|
+
pathArguments: [],
|
|
85
|
+
stage: "validate",
|
|
86
|
+
tool
|
|
87
|
+
})
|
|
88
|
+
])
|
|
89
|
+
}
|
package/src/backends/go.js
CHANGED
|
@@ -6,7 +6,7 @@ import {validateBackendModule, emitExpression} from "./shared.js"
|
|
|
6
6
|
import {emitScalarType} from "./scalars.js"
|
|
7
7
|
import {SourceWriter} from "./writer.js"
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
export const goModuleManifest = "module example.com/semantifold/generated\n\ngo 1.26.0\n"
|
|
10
10
|
const binarySyntax = Object.freeze({
|
|
11
11
|
BooleanAnd: "&&", BooleanEqual: "==", BooleanNotEqual: "!=", BooleanOr: "||",
|
|
12
12
|
IntegerAdd: "+", IntegerEqual: "==", IntegerGreaterThan: ">", IntegerGreaterThanOrEqual: ">=",
|
|
@@ -38,7 +38,7 @@ export function generateGoModule({filename, mapDirective, module, sourceMapFilen
|
|
|
38
38
|
if (!root) throw new Error("Validated Go module omitted its canonical root provenance.")
|
|
39
39
|
return {
|
|
40
40
|
artifacts: [{
|
|
41
|
-
content:
|
|
41
|
+
content: goModuleManifest,
|
|
42
42
|
contentKind: "text",
|
|
43
43
|
mediaType: "text/plain",
|
|
44
44
|
ownership: "generated",
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
import {SemantifoldDiagnostic} from "../diagnostic.js"
|
|
5
|
+
import {deterministicEnvironment} from "../toolchains.js"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Constructs Java's non-executing compiler plan from staged generated artifacts.
|
|
9
|
+
* @param {Readonly<{
|
|
10
|
+
* artifacts: import("../semantic/types.js").GeneratedArtifactSet,
|
|
11
|
+
* buildPath: string,
|
|
12
|
+
* projectId: string,
|
|
13
|
+
* sourcePath: string,
|
|
14
|
+
* targetId: string,
|
|
15
|
+
* tools: readonly import("../semantic/types.js").DiscoveredToolchain[]
|
|
16
|
+
* }>} context - Exact validated candidate context.
|
|
17
|
+
* @returns {import("../semantic/types.js").TargetCheckPlan} Immutable javac plan.
|
|
18
|
+
*/
|
|
19
|
+
export function createJavaCheckPlan(context) {
|
|
20
|
+
const javac = context.tools.find(({id}) => id == "javac")
|
|
21
|
+
|
|
22
|
+
if (!javac) {
|
|
23
|
+
throw new SemantifoldDiagnostic({
|
|
24
|
+
code: "INVALID_TARGET_CHECK_PLAN",
|
|
25
|
+
language: "java",
|
|
26
|
+
message: "Java developer checks require the declared 'javac' toolchain."
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
const artifactPaths = context.artifacts.artifacts
|
|
30
|
+
.filter(artifact => artifact.path.endsWith(".java"))
|
|
31
|
+
.map(artifact => path.join(context.sourcePath, artifact.path))
|
|
32
|
+
|
|
33
|
+
if (artifactPaths.length == 0) {
|
|
34
|
+
throw new SemantifoldDiagnostic({
|
|
35
|
+
code: "INVALID_TARGET_CHECK_PLAN",
|
|
36
|
+
language: "java",
|
|
37
|
+
message: "Java developer checks require at least one staged '.java' artifact."
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
const argv = Object.freeze(["-d", context.buildPath, ...artifactPaths])
|
|
41
|
+
const pathArguments = Object.freeze([
|
|
42
|
+
Object.freeze({index: 1, ownership: /** @type {const} */ ("build")}),
|
|
43
|
+
...artifactPaths.map((_, index) => Object.freeze({index: index + 2, ownership: /** @type {const} */ ("source")}))
|
|
44
|
+
])
|
|
45
|
+
const stage = Object.freeze({
|
|
46
|
+
argv,
|
|
47
|
+
cwd: context.sourcePath,
|
|
48
|
+
environment: deterministicEnvironment({}),
|
|
49
|
+
environmentPaths: Object.freeze([]),
|
|
50
|
+
executable: javac.executable,
|
|
51
|
+
inputHash: null,
|
|
52
|
+
inputs: Object.freeze(artifactPaths),
|
|
53
|
+
output: Object.freeze({
|
|
54
|
+
mediaType: "application/java-vm",
|
|
55
|
+
ownership: /** @type {const} */ ("build"),
|
|
56
|
+
path: context.buildPath,
|
|
57
|
+
role: "compiler-output"
|
|
58
|
+
}),
|
|
59
|
+
pathArguments,
|
|
60
|
+
stage: /** @type {const} */ ("compile"),
|
|
61
|
+
tool: javac,
|
|
62
|
+
transientPaths: Object.freeze([])
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
return Object.freeze({
|
|
66
|
+
artifactPaths: Object.freeze(artifactPaths),
|
|
67
|
+
buildPath: context.buildPath,
|
|
68
|
+
mode: /** @type {const} */ ("developer-check"),
|
|
69
|
+
projectId: context.projectId,
|
|
70
|
+
schema: /** @type {const} */ ("SemantifoldTargetCheckPlan"),
|
|
71
|
+
sourcePath: context.sourcePath,
|
|
72
|
+
stages: Object.freeze([stage]),
|
|
73
|
+
target: "java",
|
|
74
|
+
targetId: context.targetId,
|
|
75
|
+
version: /** @type {const} */ (1)
|
|
76
|
+
})
|
|
77
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
import {checkArtifacts, checkPlan, checkStage, checkTool, pathArgument} from "./check-plan.js"
|
|
5
|
+
import {SemantifoldDiagnostic} from "../diagnostic.js"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Constructs JavaScript's non-executing parse-check plan.
|
|
9
|
+
* @param {import("../language-registry.js").TargetCheckPlanContext} context - Validated candidate context.
|
|
10
|
+
* @returns {import("../semantic/types.js").TargetCheckPlan} Immutable JavaScript plan.
|
|
11
|
+
*/
|
|
12
|
+
export function createJavaScriptCheckPlan(context) {
|
|
13
|
+
const tool = checkTool(context, "node", "javascript")
|
|
14
|
+
const artifacts = checkArtifacts(context, artifact => artifact.path.endsWith(".js") || path.basename(artifact.path) == "package.json",
|
|
15
|
+
"javascript", "only staged '.js' artifacts and package manifests")
|
|
16
|
+
const sources = artifacts.filter(artifact => artifact.endsWith(".js"))
|
|
17
|
+
const manifests = artifacts.filter(artifact => artifact.endsWith("package.json"))
|
|
18
|
+
|
|
19
|
+
if (sources.length == 0) {
|
|
20
|
+
throw new SemantifoldDiagnostic({code: "INVALID_TARGET_CHECK_PLAN", language: "javascript",
|
|
21
|
+
message: "JavaScript developer checks require at least one staged '.js' artifact."})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return checkPlan(context, "javascript", artifacts, sources.map((source, index) => checkStage({
|
|
25
|
+
argv: ["--check", source],
|
|
26
|
+
cwd: context.sourcePath,
|
|
27
|
+
inputs: [source, ...(index == 0 ? manifests : [])],
|
|
28
|
+
output: null,
|
|
29
|
+
pathArguments: [pathArgument(1, "source")],
|
|
30
|
+
stage: "validate",
|
|
31
|
+
tool
|
|
32
|
+
})))
|
|
33
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import path from "node:path"
|
|
4
|
+
import {
|
|
5
|
+
checkArtifacts,
|
|
6
|
+
checkOutput,
|
|
7
|
+
checkPlan,
|
|
8
|
+
checkStage,
|
|
9
|
+
checkTool,
|
|
10
|
+
environmentPath,
|
|
11
|
+
pathArgument
|
|
12
|
+
} from "./check-plan.js"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Constructs Kotlin/JVM's non-executing compiler plan.
|
|
16
|
+
* @param {import("../language-registry.js").TargetCheckPlanContext} context - Validated candidate context.
|
|
17
|
+
* @returns {import("../semantic/types.js").TargetCheckPlan} Immutable Kotlin plan.
|
|
18
|
+
*/
|
|
19
|
+
export function createKotlinCheckPlan(context) {
|
|
20
|
+
const tool = checkTool(context, "kotlinc", "kotlin")
|
|
21
|
+
const artifacts = checkArtifacts(context, artifact => artifact.path.endsWith(".kt"), "kotlin", "only staged '.kt' artifacts")
|
|
22
|
+
const classes = path.join(context.buildPath, "classes")
|
|
23
|
+
const home = path.join(context.buildPath, "home")
|
|
24
|
+
const cache = path.join(context.buildPath, "cache")
|
|
25
|
+
const temporary = path.join(context.buildPath, "tmp")
|
|
26
|
+
|
|
27
|
+
return checkPlan(context, "kotlin", artifacts, [checkStage({
|
|
28
|
+
argv: ["-language-version", "2.4", "-api-version", "2.4", "-jvm-target", "25", "-Werror", ...artifacts, "-d", classes],
|
|
29
|
+
cwd: context.sourcePath,
|
|
30
|
+
environment: {HOME: home, TMPDIR: temporary, XDG_CACHE_HOME: cache},
|
|
31
|
+
environmentPaths: [environmentPath("HOME", "build"), environmentPath("TMPDIR", "build"), environmentPath("XDG_CACHE_HOME", "build")],
|
|
32
|
+
inputs: artifacts,
|
|
33
|
+
output: checkOutput(context.buildPath, "application/java-vm", "compiler-output"),
|
|
34
|
+
pathArguments: [
|
|
35
|
+
...artifacts.map((_, index) => pathArgument(7 + index, "source")),
|
|
36
|
+
pathArgument(8 + artifacts.length, "build")
|
|
37
|
+
],
|
|
38
|
+
stage: "compile",
|
|
39
|
+
tool
|
|
40
|
+
})])
|
|
41
|
+
}
|
package/src/backends/kotlin.js
CHANGED
|
@@ -15,7 +15,7 @@ export const kotlinArtifactMetadata = Object.freeze({
|
|
|
15
15
|
toolchain: "kotlinc",
|
|
16
16
|
version: "2.4.20"
|
|
17
17
|
}),
|
|
18
|
-
run: Object.freeze({arguments: Object.freeze(["-jar", "Program.jar"]), toolchain: "java25", version: "25.0.4
|
|
18
|
+
run: Object.freeze({arguments: Object.freeze(["-jar", "Program.jar"]), toolchain: "java25", version: "25.0.4.1"})
|
|
19
19
|
})
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {checkArtifacts, checkPlan, checkStage, checkTool, pathArgument} from "./check-plan.js"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Constructs PHP's non-executing syntax-check plan.
|
|
7
|
+
* @param {import("../language-registry.js").TargetCheckPlanContext} context - Validated candidate context.
|
|
8
|
+
* @returns {import("../semantic/types.js").TargetCheckPlan} Immutable PHP plan.
|
|
9
|
+
*/
|
|
10
|
+
export function createPhpCheckPlan(context) {
|
|
11
|
+
const tool = checkTool(context, "php82", "php")
|
|
12
|
+
const artifacts = checkArtifacts(context, artifact => artifact.path.endsWith(".php"), "php", "only staged '.php' artifacts")
|
|
13
|
+
|
|
14
|
+
return checkPlan(context, "php", artifacts, artifacts.map(artifact => checkStage({
|
|
15
|
+
argv: ["-n", "-l", artifact],
|
|
16
|
+
cwd: context.sourcePath,
|
|
17
|
+
inputs: [artifact],
|
|
18
|
+
output: null,
|
|
19
|
+
pathArguments: [pathArgument(2, "source")],
|
|
20
|
+
stage: "validate",
|
|
21
|
+
tool
|
|
22
|
+
})))
|
|
23
|
+
}
|
package/src/backends/program.js
CHANGED
|
@@ -25,6 +25,23 @@ const programTargets = new Set(["php", "ruby", "javascript", "typescript", "java
|
|
|
25
25
|
/** @type {Readonly<Set<import("../semantic/types.js").BackendLanguage>>} */
|
|
26
26
|
const programApplicationTargets = new Set(["android", "ios", "flutter"])
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Reports whether program generation implements one registered target/role combination.
|
|
30
|
+
* @param {string} language - Registered target identity.
|
|
31
|
+
* @param {string} role - Explicit project target role.
|
|
32
|
+
* @returns {boolean} Whether complete semantic programs support the combination.
|
|
33
|
+
*/
|
|
34
|
+
export function supportsProgramArtifactRole(language, role) {
|
|
35
|
+
if (role == "text") {
|
|
36
|
+
return programTargets.has(/** @type {import("../semantic/types.js").SemanticLanguage} */ (language))
|
|
37
|
+
}
|
|
38
|
+
if (role == "application") {
|
|
39
|
+
return programApplicationTargets.has(/** @type {import("../semantic/types.js").BackendLanguage} */ (language))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
/**
|
|
29
46
|
* Validates and prepares a complete semantic program for a non-text backend without allocating a writer.
|
|
30
47
|
* @param {object} input - Backend preflight request.
|