Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 9 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,9 @@ jobs:
# `dune runtest` — not an optional extra that merely widens
# coverage. Dropping it turns the walker suite red, which is
# the intended behaviour: see that file's header comment.
# Pin exact version + --ignore-scripts: Sonar githubactions:S8543
# (unlocked versions) and S6505 (lifecycle scripts). Same binary
# the grammar's package.json asks for (^0.25.0 floor).
run: npm install -g --ignore-scripts tree-sitter-cli@0.25.0
# GitHub release binary (no npm postinstall). --ignore-scripts
# on tree-sitter-cli@0.25.0 left the `tree-sitter` binary missing.
run: ./scripts/install-tree-sitter-cli.sh
- name: Build pinned tree-sitter-rescript grammar
run: ./editors/tree-sitter-rescript/scripts/install.sh
- name: Build
Expand Down Expand Up @@ -241,10 +240,9 @@ jobs:
# so this job needs the same grammar prerequisites as `build`.
# Before the skip was removed, this job was green while running
# zero walker tests.
# Pin exact version + --ignore-scripts: Sonar githubactions:S8543
# (unlocked versions) and S6505 (lifecycle scripts). Same binary
# the grammar's package.json asks for (^0.25.0 floor).
run: npm install -g --ignore-scripts tree-sitter-cli@0.25.0
# GitHub release binary (no npm postinstall). --ignore-scripts
# on tree-sitter-cli@0.25.0 left the `tree-sitter` binary missing.
run: ./scripts/install-tree-sitter-cli.sh
- name: Build pinned tree-sitter-rescript grammar
run: ./editors/tree-sitter-rescript/scripts/install.sh
- name: Run tests with bisect_ppx instrumentation
Expand Down Expand Up @@ -347,17 +345,9 @@ jobs:
with:
node-version: "20"
- name: Install tree-sitter CLI
# npm install of tree-sitter-cli is the fast CI path (~5 s vs.
# ~5 min for `cargo install tree-sitter-cli`). The repo's
# preferred local path is cargo (see editors/tree-sitter-rescript/
# README.md) — both produce the same `tree-sitter` binary that
# the install script invokes via `command -v`. The version
# tracks `tree-sitter-rescript`'s package.json devDependency
# range.
# Pin exact version + --ignore-scripts: Sonar githubactions:S8543
# (unlocked versions) and S6505 (lifecycle scripts). Same binary
# the grammar's package.json asks for (^0.25.0 floor).
run: npm install -g --ignore-scripts tree-sitter-cli@0.25.0
# GitHub release binary (no npm postinstall). --ignore-scripts
# on tree-sitter-cli@0.25.0 left the `tree-sitter` binary missing.
run: ./scripts/install-tree-sitter-cli.sh
- name: Build pinned tree-sitter-rescript grammar
# Direct script invocation rather than `just install-grammar` —
# GitHub Actions runners do not ship `just` preinstalled, and
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/workflow-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ jobs:
errors=0
for f in .github/workflows/*.yml .github/workflows/*.yaml; do
[ -f "$f" ] || continue
if ! head -1 "$f" | grep -q "SPDX-License-Identifier"; then
# actions-lock prepends a managed-by comment, so SPDX is
# often line 2. Accept it anywhere in the first 5 lines.
if ! head -5 "$f" | grep -q "SPDX-License-Identifier"; then
echo "ERROR: $f missing SPDX header"
errors=$((errors + 1))
fi
Expand Down
23 changes: 23 additions & 0 deletions affinescript-vite/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
= affinescript-vite
:toc: macro

toc::[]

Vite plugin **scaffold** for AffineScript (issue #56 remainder).
Not a production bundler integration.

== Use

[source,javascript]
----
import affinescript from "affinescript-vite";

export default {
plugins: [affinescript()],
};
----

`*.affine` modules are compiled with `affinescript compile --bun-esm`.
The compiler must be on `PATH` (or set `AFFINESCRIPT` / `compiler` option).

Deno-ESM is retired; the emit target is Bun-ESM.
42 changes: 42 additions & 0 deletions affinescript-vite/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MPL-2.0
/**
* Vite plugin scaffold for AffineScript (#56).
*
* Transforms `*.affine` sources by shelling out to `affinescript compile
* --bun-esm`. This is a compile-pass wiring, not a production bundler
* integration: the compiler must be on PATH, and the plugin does not
* ship a JS-hosted AffineScript frontend.
*/
import { spawnSync } from "node:child_process";
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

export default function affinescriptVite(options = {}) {
const compiler = options.compiler || process.env.AFFINESCRIPT || "affinescript";
return {
name: "affinescript",
enforce: "pre",
async transform(_code, id) {
const filename = id.split("?")[0];
if (!filename.endsWith(".affine")) return null;
const dir = mkdtempSync(join(tmpdir(), "affinescript-vite-"));
const src = join(dir, "input.affine");
const out = join(dir, "out.bun.js");
try {
writeFileSync(src, _code);
const r = spawnSync(compiler, ["compile", src, "-o", out, "--bun-esm"], {
encoding: "utf8",
});
if (r.status !== 0) {
const msg = (r.stderr || r.stdout || "affinescript compile failed").trim();
this.error(msg);
return null;
}
return { code: readFileSync(out, "utf8"), map: null };
} finally {
rmSync(dir, { recursive: true, force: true });
}
},
};
}
14 changes: 14 additions & 0 deletions affinescript-vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "affinescript-vite",
"version": "0.0.1",
"description": "Vite plugin scaffold: compile .affine files with --bun-esm",
"license": "MPL-2.0",
"type": "module",
"main": "index.js",
"exports": {
".": "./index.js"
},
"peerDependencies": {
"vite": ">=5"
}
}
5 changes: 4 additions & 1 deletion docs/ECOSYSTEM.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ against a real Int-handle host DOM, mutation log asserted.
`stdlib/Dom.affine` + `stdlib/Console.affine`. Remaining: full idaptik
surface.

|`affinescript-vite` |scaffold |Build-tool integration shell.
|`affinescript-vite` |scaffold |In-tree Vite plugin shell
(`affinescript-vite/`): transforms `*.affine` via
`affinescript compile --bun-esm`. Compiler must be on PATH. Not a
production bundler.

|`affinescript-deno-test` |historical |Smoke-test harness from the retired
Deno-ESM target. JS-host ESM is Bun-ESM (`--bun-esm`).
Expand Down
19 changes: 8 additions & 11 deletions lib/codegen_deno.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,14 @@ let rec gen_expr ctx (expr : expr) : string =
| ExprReturn (Some e) -> iife ctx ("return " ^ gen_expr ctx e ^ ";")
| ExprReturn None -> iife ctx "return Unit;"
(* #459: break/continue lower to the corresponding JS keywords. The
wrapping Iram) -> mangle p.p_name.name) elam_params in
wrapping IIFE pattern used for `return` doesn't work here — JS's
`break`/`continue` only target the nearest enclosing loop and an
IIFE wraps the keyword in a new function frame. Emit a bare
statement and rely on the parent block-flatten machinery. *)
| ExprBreak _ -> iife ctx "break;"
| ExprContinue _ -> iife ctx "continue;"
| ExprLambda { elam_params; elam_body; elam_ret_ty = _ } ->
let ps = List.map (fun (p : param) -> mangle p.p_name.name) elam_params in
"((" ^ String.concat ", " ps ^ ") => " ^ gen_expr ctx elam_body ^ ")"
| ExprTry { et_body; et_catch; et_finally } ->
gen_try ctx et_body et_catch et_finally
Expand Down Expand Up @@ -1800,16 +1807,6 @@ let rec type_expr_name : type_expr -> string option = function
| TyOwn t | TyRef (_, t) | TyMut (_, t) -> type_expr_name t
| _ -> None

(* The struct (if any, among [known]) that [fd]'s first parameter is typed
as — i.e. [fd] is a receiver-first method of that struct. *)
let receiver_struct ~(known : (string, 'a) Hashtbl.t) (fd : fn_decl)
: (string * string) option =
match fd.fd_params withtion = function
| TyCon id | TyVar id -> Some id.name
| TyApp (id, _) -> Some id.name
| TyOwn t | TyRef (_, t) | TyMut (_, t) -> type_expr_name t
| _ -> None

(* The struct (if any, among [known]) that [fd]'s first parameter is typed
as — i.e. [fd] is a receiver-first method of that struct. *)
let receiver_struct ~(known : (string, 'a) Hashtbl.t) (fd : fn_decl)
Expand Down
38 changes: 38 additions & 0 deletions scripts/install-tree-sitter-cli.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MPL-2.0
# Install a pinned tree-sitter CLI binary from GitHub Releases.
#
# Used by CI instead of `npm install -g --ignore-scripts tree-sitter-cli`:
# that package's binary is fetched in a postinstall script, so
# --ignore-scripts (Sonar S6505) leaves `tree-sitter` missing (ENOENT).
# A release tarball has no lifecycle scripts.
set -euo pipefail

VER="${TREE_SITTER_CLI_VERSION:-0.25.0}"
DEST="${TREE_SITTER_CLI_DEST:-/usr/local/bin/tree-sitter}"

arch="$(uname -m)"
case "$arch" in
x86_64|amd64) ts_arch=x64 ;;
aarch64|arm64) ts_arch=arm64 ;;
*)
echo "error: unsupported arch $arch" >&2
exit 1
;;
esac

url="https://github.com/tree-sitter/tree-sitter/releases/download/v${VER}/tree-sitter-linux-${ts_arch}.gz"
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
curl -fsSL "$url" | gunzip > "$tmp"

Check warning on line 27 in scripts/install-tree-sitter-cli.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enforcing HTTPS here might allow for redirections to insecure websites. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_affinescript&issues=AaDDlgozy4Y3MS4X8oEF&open=AaDDlgozy4Y3MS4X8oEF&pullRequest=761
chmod +x "$tmp"

if [ -w "$(dirname "$DEST")" ]; then

Check failure on line 30 in scripts/install-tree-sitter-cli.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_affinescript&issues=AaDDlgozy4Y3MS4X8oEG&open=AaDDlgozy4Y3MS4X8oEG&pullRequest=761
mv "$tmp" "$DEST"
trap - EXIT
else
sudo mv "$tmp" "$DEST"
trap - EXIT
fi

"$DEST" --version
Loading