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
25 changes: 25 additions & 0 deletions .github/workflows/extended_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ jobs:
steps:
- name: "SCM Checkout"
uses: actions/checkout@v4
with:
# Full history so the lint step can `git diff` against the PR base branch.
fetch-depth: 0

- name: "Install CMake and Ninja"
uses: lukka/get-cmake@latest
Expand Down Expand Up @@ -178,6 +181,7 @@ jobs:
set -eux
cmake --build ./build --config Release --target all_utils_exe
$BIN/daslang -exe -output ./bin/das-fmt ./utils/das-fmt/dasfmt.das
$BIN/daslang -exe -output ./bin/das-lint ./utils/lint/main.das

- name: "Sequence release smoke test"
# Full daspkg install -> release -> launch cycle on the in-tree sequence
Expand Down Expand Up @@ -218,6 +222,21 @@ jobs:
$BIN/daslang ./utils/das-fmt/dasfmt.das -- --path ./ --verify
$BIN/das-fmt.exe --path ./ --verify

- name: "Run lint on changed .das files"
if: matrix.target == 'linux'
run: |
set -eux
BASE_REF="${{ github.event.pull_request.base.ref }}"
BASE_REF="${BASE_REF:-master}"
mapfile -t CHANGED < <(git diff --name-only --diff-filter=AM "origin/${BASE_REF}...HEAD" -- '*.das')
if [ ${#CHANGED[@]} -eq 0 ]; then
echo "no .das files changed; skipping lint"
exit 0
fi
echo "linting: ${CHANGED[*]}"
$BIN/daslang ./utils/lint/main.das -- "${CHANGED[@]}" --quiet
$BIN/das-lint.exe "${CHANGED[@]}" --quiet

- name: "Test daslang_static"
run: |
set -eux
Expand All @@ -227,6 +246,12 @@ jobs:
$BIN/daslang _dasroot_/dastest/dastest.das -- --color --failures-only --test ./tests --ser serialized.bin
$BIN/daslang _dasroot_/dastest/dastest.das -- --color --failures-only --test ./tests --deser serialized.bin

- name: "Test MCP tools"
if: matrix.target == 'linux'
run: |
set -eux
$BIN/daslang _dasroot_/dastest/dastest.das -- --color --failures-only --test ./utils/mcp/test_tools.das

- name: "Run self-binder (bind_clangbind.das)"
if: matrix.target == 'linux'
run: |
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ build-asan/
build-ubsan/
build-linux-asan/
build-linux/
build_eastl/
# EASTL local-verify checkouts (build_eastl uses these via -isystem)
eastl/
eabase/
# docs
site/doc-latex/
# daspkg per-package cmake build dirs (utils/daspkg/commands.das:976 -> {pkg_dir}/_build)
Expand Down Expand Up @@ -97,6 +101,11 @@ modules/.daspkg_cache/
modules/.daspkg.log
examples/**/modules/
utils/**/modules/
# Exception: MCP test fixture for project_root flag (utils/mcp/test_tools.das
# Tier 1 tests need a daspkg-style modules/<mod>/.das_module layout to verify
# that -project_root flows through correctly).
!utils/mcp/tests/_pretend_root/modules/
!utils/mcp/tests/_pretend_root/modules/**

# Claude Code (local settings + runtime state)
.claude/
Expand Down
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Task-specific instructions are split into skill files under `skills/`. You MUST
| `skills/writing_benchmarks.md` | Writing/running `benchmarks/` files |
| `skills/daspkg.md` | Running daspkg commands, `.das_package` manifests |
| `skills/dynamic_modules.md` | `.das_module` descriptors, adding modules under `modules/` |
| `skills/external_module_debugging.md` | Working on an external daslang module (dasImgui, dasPUGIXML, dasSQLITE, etc.) locally — need to run/lint/test from a standalone daslang.exe or via MCP before push-to-CI. Covers the `<DummyRoot>/modules/<your-module>` junction pattern + `project_root` MCP arg |
| `skills/install_instructions.md` | Updating `install/CLAUDE.md` or `install/skills/` for the shipped SDK |
| `skills/aot_testing.md` | AOT test files, `test_aot` binary, `Module::aotRequire()`, AOT hash mismatches |
| `skills/visitor_gen_bind.md` | Adding `Visitor` virtual methods / `canVisit*` gates / `gen_bind.das` regen |
Expand Down Expand Up @@ -269,6 +270,9 @@ Full migration table (when reading older docs that say `var inscope` or `<-` for
| `int(BfT.a) \| int(BfT.b)` (same bitfield, or enum with `operator \|`) | `int(BfT.a \| BfT.b)` | PERF019: collapse two int casts to one. Const-foldable forms only surface under lint policies |
| `foo \|= BfT.m` / `foo &= ~BfT.m` (bitfield `foo`, single named bit) | `foo.m = true` / `foo.m = false` | STYLE022: bitfield-as-field assignment reads bit-name-first, drops the `~` for clears |
| `uint(bf & BfT.m) != 0u` / `int(bf & BfT.m) == 0` (bitfield `bf`, single named bit) | `bf.m` / `!bf.m` | STYLE023: bitfield-as-field read; drop the int cast + `!= 0` / `== 0` compare |
| `unsafe(x + y)` / `unsafe { let d = x + y }` where nothing inside requires unsafe | drop the wrap | STYLE024: redundant `unsafe` — flagged when no descendant matches a known inherently-unsafe shape (reinterpret/upcast cast, `delete`, `addr`, table-index, variant-write, ExprCallFunc with `unsafeOperation`). Macro-generated subtrees (`genFlags.generated == true`) skipped per design |
| `unsafe { stmt1; stmt2; stmt_needing_unsafe }` (only ONE stmt actually needs unsafe) | `stmt1; stmt2; unsafe(<sub-expr>)` | STYLE025: narrow block-form unsafe to expression-form on the single unsafe-needing statement. Silent when ≥2 statements need unsafe (block is justified) |
| `unsafe { ...; unsafe { ... }; ... }` (nested `unsafe { }` block) | drop the inner wrap | STYLE026: outer `unsafe` already covers the whole inner scope, so the inner block is pure noise. Closure / lambda / generator bodies are NOT nested for this rule — they execute in a separate context where the outer wrap does not propagate |

For path/filename ops use `fio` helpers (`base_name`/`dir_name`/`path_join`/etc.) — see `skills/filesystem.md`. Never hand-roll `rfind("/")` / slice — misses Windows separators.

Expand Down
4 changes: 2 additions & 2 deletions cmake/das_config_eastl/das_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ using std::thread;
using std::unique_lock;
} // namespace das

#if (!defined(DAS_ENABLE_EXCEPTIONS)) || (!DAS_ENABLE_EXCEPTIONS)
#define FMT_THROW(x) das::das_throw(((x).what()))
namespace das {
void das_throw(const char * msg);
}
#if (!defined(DAS_ENABLE_EXCEPTIONS)) || (!DAS_ENABLE_EXCEPTIONS)
#define FMT_THROW(x) das::das_throw(((x).what()))
#endif

#if DAS_CUSTOM_HASH
Expand Down
8 changes: 2 additions & 6 deletions daslib/archive.das
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,7 @@ def public serialize(var arch : Archive; var value : auto(TT)&) {
delete value
var index : int
arch |> read_raw(index)
unsafe {
value |> set_variant_index(index)
}
unsafe(value |> set_variant_index(index))
} else {
var index = variant_index(value)
arch |> write_raw(index)
Expand Down Expand Up @@ -335,9 +333,7 @@ def public serialize(var arch : Archive; var value : array<auto(TT)>) {
arch.stream->read(unsafe(addr(value[0])), len * typeinfo sizeof(type<TT>))
}
} else {
unsafe {
value |> resize(len)
}
unsafe(value |> resize(len))
for (element in value) {
arch |> _::serialize(element)
}
Expand Down
8 changes: 2 additions & 6 deletions daslib/array_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ def public temp_array(var data : auto? ==const; lenA : int; a : auto(TT)) : arra
//! * data memory does not change within the lifetime of the returned array
var res : array<TT -const -#>
if (lenA >= 1) {
unsafe {
_builtin_make_temp_array(res, data, lenA)
}
unsafe(_builtin_make_temp_array(res, data, lenA))
}
return <- res
}
Expand All @@ -101,9 +99,7 @@ def public temp_array(data : auto? ==const; lenA : int; a : auto(TT)) : array<TT
//! * data memory does not change within the lifetime of the returned array
var res : array<TT -const -#>
if (lenA >= 1) {
unsafe {
_builtin_make_temp_array(res, data, lenA)
}
unsafe(_builtin_make_temp_array(res, data, lenA))
}
return <- res
}
Expand Down
14 changes: 5 additions & 9 deletions daslib/jobque_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,8 @@ def for_each(channel : Channel?; blk : block<(res : auto(TT)#) : void>) {
void_data = vd
}
if (void_data == null) break
unsafe {
let typed_data = reinterpret<TT?#> void_data
invoke(blk, *typed_data)
}
let typed_data = unsafe(reinterpret<TT?#> void_data)
invoke(blk, *typed_data)
}
}

Expand Down Expand Up @@ -165,11 +163,9 @@ def pop_one(channel : Channel?; blk : block<(res : auto(TT)#) : void>) {
void_data = vd
}
if (void_data == null) return false
unsafe {
let typed_data = reinterpret<TT?#> void_data
invoke(blk, *typed_data)
return true
}
let typed_data = unsafe(reinterpret<TT?#> void_data)
invoke(blk, *typed_data)
return true
}

def pop_and_clone_one(channel : Channel?; blk : block<(res : auto(TT)#) : void>) {
Expand Down
11 changes: 2 additions & 9 deletions daslib/json_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,7 @@ def from_JV(v : JsonValue const explicit?; ent : auto(EnumT); defV : EnumT = def
var res : auto(EnumTT) = default<EnumT>
let ti = typeinfo rtti_typeinfo(type<EnumT>)
for (ef in *ti.enumType) {
if (name == ef.name) {
unsafe {
res = reinterpret<EnumTT>(ef.value)
}
return res
}
return unsafe(reinterpret<EnumTT>(ef.value)) if (name == ef.name)
}
panic("not a valid enumeration {name} in {typeinfo typename(type<EnumT>)}")
} else {
Expand Down Expand Up @@ -493,9 +488,7 @@ def from_JV(v : JsonValue const explicit?; anything : auto(TT)) {
let vv : JsonValue? = (v.value as _object)?["$variant"] ?? default<JsonValue?>
if (vv == null || !((vv.value is _number) || (vv.value is _longint))) return <- ret
let index = (vv.value is _number) ? int(vv.value as _number) : int(vv.value as _longint)
unsafe {
set_variant_index(ret, index)
}
unsafe(set_variant_index(ret, index))
apply(ret) $(name : string; var field) {
(v as _object) |> get(name) $(val) {
move_to_ref(field, _::from_JV(val, decltype_noref(field)))
Expand Down
4 changes: 1 addition & 3 deletions daslib/rtti.das
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,7 @@ def type_info(vinfo : VarInfo) : TypeInfo const? {
[generic]
def RttiValue_nothing {
var t : RttiValue
unsafe {
set_variant_index(t, typeinfo variant_index<nothing>(t))
}
unsafe(set_variant_index(t, typeinfo variant_index<nothing>(t)))
return t
}

Expand Down
Loading
Loading