Skip to content

fix: typechecker hardening, stdlib wiring, and code scanning fixes#1592

Merged
SchoolyB merged 37 commits intomainfrom
dev
Apr 29, 2026
Merged

fix: typechecker hardening, stdlib wiring, and code scanning fixes#1592
SchoolyB merged 37 commits intomainfrom
dev

Conversation

@SchoolyB
Copy link
Copy Markdown
Owner

Summary

SAY-5 and others added 30 commits April 28, 2026 03:48
Closes #1572.

ez doc previously hard-coded its destination to DOCS.md in the
current working directory, with no way to redirect to a different
path. The flag is StringP("output", "o", "DOCS.md", ...) so the
default behavior is unchanged for callers that do not pass it.

generateDocs now takes the output path as a parameter and treats
"" as a fall-through to the legacy DOCS.md default. When the path
points at a nested file (e.g. docs/API.md), the parent directory
is created with os.MkdirAll before writing.

Tests cover: default path unchanged, custom path written and
DOCS.md not produced as a side effect, and parent directories
created for nested paths.
Closes #1571.

Captures the formatting conventions that already live in the
source so contributors using any EditorConfig-aware editor (VS
Code, Vim, Emacs, JetBrains, etc.) get the right defaults
without per-editor configuration.

* C/C++ — 4-space indent, matching `ezc/.clang-format`.
* Go — tabs (gofmt).
* Makefiles — tabs (required by make recipe lines).
* YAML/JSON/TOML — 2-space indent, matching the workflow files.
* Shell scripts — 2-space indent.
* Markdown — trailing whitespace preserved (hard line breaks).
* Everything — UTF-8, LF, final newline.

No source files are reformatted in this change; the .editorconfig
only changes editor behavior for *new* edits.
Bumps [actions/labeler](https://github.com/actions/labeler) from 5 to 6.
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](actions/labeler@v5...v6)

---
updated-dependencies:
- dependency-name: actions/labeler
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
feat(cli): add -o/--output flag to ez doc
chore: add .editorconfig for consistent formatting
…#1580)

- random.seed(): added C impl + codegen handler (typechecker already registered)
- json.format(): added codegen handler as alias for encode
- csv.format(): added codegen handler as alias for encode
- csv.headers(): added C impl + codegen handler to extract first row
- server.cors(): added C impl with CORS header injection + codegen handler
- server.use(): added C impl with middleware support + codegen handler
- sync.try_lock(): added C impl wrapping pthread_mutex_trylock + codegen handler + fixed typechecker return type from void to bool
…ns (#1580)

Remove quote wrapping from all direct print functions (println, print,
eprintln, eprint) for strings and chars. Strings/chars printed directly
now output raw values without surrounding quotes, matching behavior of
C, Go, Rust, Odin, and every comparable language.

Quotes are preserved only when strings/chars appear as elements inside
printed containers (arrays, maps, structs) where they disambiguate
element boundaries.

- Removed putchar/fputc quote wrapping from 8 builtin print functions
- Removed fputc quote wrapping from 2 fmt module print functions
- Added in_container parameter to emit_value_print() in codegen
- Updated 34 unit test expectations to match unquoted output
- random_seed.ez: deterministic seeding, seed(0), seed+rand_float
- json_format.ez: format() alias parity with encode() for all types
- csv_format_headers.ez: format() alias + headers() extraction
- sync_try_lock.ez: non-blocking lock returns bool, usable in if
- server_cors_use.ez: cors() with wildcard/specific/empty origins
When a wildcard-typed parameter (?) was used in string interpolation,
the codegen defaulted to TK_INT and emitted (long long)(x), causing
a C compiler error for non-integer types like string, float, bool.

Added wildcard_binding resolution in both passes of the interpolation
handler, matching the existing pattern in the infix handler. Now
resolves the concrete type before selecting the format specifier.
Covers wildcard (?) params in string interpolation for int, float,
string, bool, and reuse of the same generic function with different
concrete types.
…mports (#1585)

- Registered HttpRequest as a struct with 6 fields (method, path, body,
  query, headers, params) matching the C EzRequest layout
- Moved HttpResponse and HttpRequest registration after import collection
  so they are only available when server or http module is imported
- Renamed Request to HttpRequest in STANDARD.md for consistency
- Added server.cors() and server.use() to STANDARD.md routing table
Codegen was emitting EzStruct_HttpRequest/EzStruct_HttpResponse for
the HTTP types since ez_type_to_c_cg treated them as user-defined
structs. Added special-case mappings: HttpRequest -> EzRequest and
HttpResponse -> EzResponse, matching the C types in ez_server.h.

The server's add_route handler cast is hardcoded to
(EzResponse (*)(EzRequest)), so these mappings ensure user-written
handler functions compile correctly.
Add E4016 validation for undefined type names across three code paths:
- Type annotations on variables, function params, and return types
- Struct literal syntax (TypeName{})
- tc_type_from_name() now returns TYPE_UNKNOWN for unregistered uppercase
  names after the registration phase completes (guarded by registering flag
  to preserve forward references during declaration registration)
…1585)

- server_http_types.ez: HttpRequest as param, HttpResponse as return/var type
- E4016_undefined_type_no_import.ez: HttpRequest/HttpResponse rejected without import
- E4016_undefined_struct_type.ez: undefined capitalized type rejected
HttpRequest is exclusively a server module type. Split the registration
block so HttpResponse is available from either http or server imports,
while HttpRequest is only registered when server is imported.
…1585)

Verifies HttpRequest is rejected when only the http module is imported —
the type is scoped to the server module only.
…d e2e expectations (#1585)

Bug 1: E4016 check in tc_type_from_name() falsely rejected the built-in
Error type which is mapped directly in codegen without struct registration.
Added exemption for "Error" before returning TYPE_UNKNOWN.

Bug 2: Updated 9 remaining e2e test expectations that still had quoted
string output from type_of() and mem_alloc after the quote encapsulation
revert.
type_of(Foo) where Foo is a struct/enum name silently returned "unknown"
at runtime. Added E3084 validation that checks if the argument is a
NODE_LABEL matching a registered struct or enum name without a
corresponding variable in scope, and emits a clear error directing the
user to pass a value instead.
- E3084_type_of_type_name.ez: struct name passed to type_of() rejected
- E3084_type_of_enum_name.ez: enum name passed to type_of() rejected
…g containment (#1589, #1590)

Add E3085 type validation for in/not_in/!in operators:
- Array: left operand type must match element type
- Map: left operand type must match key type
- String: only char (character membership) and string (substring check)
  are valid left operands

Wire string containment in codegen:
- char in string emits memchr() scan
- string in string emits ez_strings_contains() substring check
- Both support negated forms (not_in, !in)
…#1589, #1590)

- string_in_operator.ez: char in string, string in string, !in variants
- E3085_in_type_mismatch_array.ez: int in [string] rejected
- E3085_in_type_mismatch_string.ez: int in string rejected
- E3085_in_type_mismatch_map.ez: string in map[int:string] rejected
type_name() returned the raw element/key type for arrays and maps,
producing confusing error messages like "cannot check if 'int' is in
'string'" when the container is [string]. Added TK_ARRAY and TK_MAP
formatting using the same ring-buffer approach as pointers, so messages
now show [string] and map[string:int] respectively.
…1587)

Struct function calls via instance dispatch (e.g. f.bar(1,2,3)) bypassed
argument count validation entirely. Added E5008 check in the instance
method call path, after the AST rewrite prepends self. Accounts for
default parameters and displays user-facing counts without self.
- E5008_struct_func_too_few_args.ez: Math.add(1) rejected, expects 2
- E5008_struct_func_too_many_args.ez: Math.zero(10, 20) rejected, expects 0
Clamp snprintf return values before accumulating into offsets to prevent
buffer overruns when truncation occurs. Affects 6 call sites:
- main.c: source file list building (2 loops)
- ez_json.c: array/map int and float encoders (4 sites)
- typechecker.c: function reference type signature builder
…g pointers

type_struct(), type_enum(), type_pointer(), and several branches in
type_from_name() stored incoming const char* pointers directly into
the static type pool without copying. If a caller ever passed a
stack-local buffer, the pool entry would hold a dangling pointer.
Added strdup() at each assignment to ensure the type pool always
owns its strings.
…rations

Building with -std=c11 hides POSIX declarations like strdup() and
readlink(). Adding -D_POSIX_C_SOURCE=200809L makes them visible,
eliminating 182 implicit function declaration warnings.
The E3013 return count check only caught when fewer values were returned
than declared (count < expected). Returning more values (e.g. return 1, 2
from a single-return function) slipped through because the condition
redundantly required count < current_return_count alongside count !=
current_return_count. Simplified to just count != current_return_count
so both too-few and too-many cases are caught.
SchoolyB and others added 7 commits April 29, 2026 16:58
- E3013_too_many_return_values.ez: 3 values from 2-return function
- E3013_too_many_return_single.ez: 2 values from single-return function
…nic builtins (#1591)

These builtins validated argument count but not types, so passing e.g.
a string to exit() or an int to panic() passed the typechecker and
crashed during C compilation. Added type checks:
- range(): start/end/step must be integer types
- exit(): argument must be integer
- panic(): argument must be string
- assert(): condition must be bool, message must be string
- sleep_s/sleep_ms/sleep_ns(): argument must be integer
- E3001_exit_non_int.ez: exit("oops") rejected
- E3001_panic_non_string.ez: panic(42) rejected
- E3001_assert_non_bool.ez: assert(42) rejected
- E3001_assert_non_string_msg.ez: assert(true, 123) rejected
- E3001_range_non_int.ez: range("ten") rejected
- E3001_sleep_non_int.ez: sleep_ms("fast") rejected
…lections (#1589)

E3085 falsely rejected enum values in maps/arrays with enum keys/elements
because the kind comparison failed (TK_ENUM vs TK_STRUCT from
type_from_name). Added name-based exemption: if the left operand's type
name matches the collection's key/element type name, skip the mismatch.
…ons/labeler-6

chore(deps): bump actions/labeler from 5 to 6
…leapis/release-please-action-5

chore(deps): bump googleapis/release-please-action from 4 to 5
@github-actions github-actions Bot added documentation Improvements or additions to documentation typechecker Related to type checking and validation module-system Related to imports, exports, and module loading stdlib General standard library issues tests Related to unit tests or test infrastructure error-messages Related to improving error messages CI/CD Continuous Integration/Continuous Deployment cli Command-line interface related ezc EZC compiler tool (EZ → C → native binary) labels Apr 29, 2026
@SchoolyB SchoolyB merged commit dd5fe8b into main Apr 29, 2026
@SchoolyB SchoolyB deleted the dev branch April 29, 2026 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD Continuous Integration/Continuous Deployment cli Command-line interface related documentation Improvements or additions to documentation error-messages Related to improving error messages ezc EZC compiler tool (EZ → C → native binary) module-system Related to imports, exports, and module loading stdlib General standard library issues tests Related to unit tests or test infrastructure typechecker Related to type checking and validation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add --output flag to ez doc command chore: add .editorconfig for consistent formatting

2 participants