V2 Roadmap#27
Draft
multiarc wants to merge 10 commits into
Draft
Conversation
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
multiarc
force-pushed
the
feature/lang_asmt
branch
from
July 7, 2026 17:52
19bbbd2 to
7db317e
Compare
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
Flip the 2.0 window defaults and complete the version shift: - Engine: OutputProfile=Html, TrimDirectiveLines=true (TemplateOptions ctors) - Generator: Heddle.Generator.props + ConfigReader code fallback -> Html/true - TemplateResolver convenience-ctor defaults -> Html/true (serve Html manifests) - Version 1.0.0 -> 2.0.0 across csproj, docs, vscode, lsp workflow, generator snapshots, CHANGELOG Fixes exposed by the flip: - Internal C# code-gen meta-templates pinned to Text (were HTML-encoding generated source) - WidenToWholeLine defensive bounds clamp (trim crash on stale block position) - Emitter records the 'html' binding name for the Html unnamed carrier (gauntlet resolution) Re-ratified goldens/tests for the new defaults; pinned the codegen-t4-successor sample to Text. Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
…y landed in the C# engine and ANTLR grammar. Migrate Ace web editor to v2 language grammar - WS1: wire JS grammar generation + propagation into the build (propagate_js.js, npm scripts); refresh stale v1.x mode-copy lexer/parser/listener to v2; CI drift guard in docs.yml. - WS2: extend heddle_highlight_rules.js to classify all v2 constructs (literals, operators, brackets, commas, function/method calls, this, prop lists, named args, slots, @elif/@else/@raw/@Profile). - WS4: rewrite beautify.js as a Heddle-aware, idempotent formatter with formatOptions schema. - WS5: parse-only worker diagnostics baseline; align messages to HED0003; toAnnotations.js. - WS6: add elif/elseif/else/profile/raw + slot out extensions, built-in functions, and v2 snippets. - WS7: register [ ] bracket pair (auto-close/skip) and outdent; folding verified. - WS8: demo.html showcases v2 constructs; demo-smoke updated. - WS9: stand up JS test harness (node:test, ace-code shim); 129 tests. - WS10: build_ace.sh picks up all js/src edits; Ace pin kept at v1.32.6. Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
multiarc
force-pushed
the
feature/lang_asmt
branch
from
July 9, 2026 07:29
9eaf197 to
38d0038
Compare
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
multiarc
force-pushed
the
feature/lang_asmt
branch
from
July 12, 2026 16:14
c19eba5 to
4845d51
Compare
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
multiarc
force-pushed
the
feature/lang_asmt
branch
from
July 12, 2026 16:16
4845d51 to
a9c7e36
Compare
Signed-off-by: Aliaksandr Kukrash <multiarc@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Heddle v2.0
The 2.0 evolution: a sandbox-safe expression tier, safe-by-default output, declarative branching, a component model, editor tooling, a build-time compiler, and a streaming render surface. Almost everything is additive and differential-gated — the dynamic engine's rendered bytes are unchanged. The breaking changes are two engine defaults flipped together and the removal of the legacy
@import()include (see Migration).Native expression tier
A sandbox-safe, Roslyn-free expression language in call parens:
@if(Count > 0),@(Price * Quantity),@(Name ?? "anon"),@(IsFeatured ? "★" : ""). Operators and literals follow the C# precedence table exactly and compile toSystem.Linq.Expressionsdelegates — no Roslyn, no arbitrary method calls. Capability is limited to properties/indexers/operators/literals plus host-registered whitelisted functions (FunctionRegistry,[ExportFunctions]).ExpressionModeselectsMemberPathsOnly/Native(default) /FullCSharp; the inner-@form stays full C#.Safe output by default
An
OutputProfile.Htmlprofile HTML-encodes the unnamed@(...)carrier, closing the XSS-by-default gap, with@raw(...)as the explicit opt-out and a@profile(html|text)directive that flips mid-document. The HTML encoder is a pluggableTemplateOptions.Encoder(System.Text.Encodings.Web.TextEncoder) — opt-in, with the default preserving the existingWebUtility.HtmlEncodebytes — and context-encoding extensions@attr/@js/@urlcover the HTML-attribute, JavaScript-string-literal, and URL-component contexts that element-text encoding does not.Declarative branching
Optional
@elif/@elseas ordinary extensions that coordinate with a preceding@if/@ifnotthrough a published local context — no new keywords, no chaining, no imperative statement structure. Text between branch blocks is stripped with a warning (industry-standard adjacency). The underlying publish/read channel (Scope.Publish/TryRead,BranchState) is public API for custom extensions to coordinate; branch-set classification is driven by[BranchRole], so a custom extension can join or form a set with the same semantics as the built-ins.Ergonomics
@for(5)/@for(Count)/@for(range(...))loop sugar (no more hand-written C# loop models), an opt-inTrimDirectiveLinesthat swallows whole-line directives' trailing newlines, and a double-render warning when a default-output definition is also called by name.Named props & slots
Definitions gain typed named parameters with defaults (
@card(Article, style: "wide", compact: true)), prop reads in bodies, and parameterized@out()slots — with abstract-definition composition and inheritance narrowing. Missing/unknown/mistyped props are positioned compile errors at the call site.Editor tooling & LSP
Editor tooling extracted as a zero-breaking-change, flag-gated projection (
Heddle.LanguageServices, null-cost when off) plus a hand-rolled LSP 3.17 server: typed member completion inside@(...), hover types, diagnostics at template positions, and go-to-definition across@<<imports (imported-file diagnostics re-anchored to the import site). Ships with a VS Code extension.Build-time precompilation
A Roslyn incremental source generator (
Heddle.Generator) compiles.heddletemplates toIProcessStrategyclasses at build time — Razor-style, byte-for-byte identical to the dynamic engine, with no runtime Heddle dependency in the generated output. Covers the full construct set (member paths, native expressions, verbatim C#,::dynamic, branches,@list/@for, definitions/props/slots,@partial,@profile,[ExportFunctions],@<<composition imports); template errors become positioned build diagnostics (HED70xx) and anything not yet emittable degrades safely to the dynamic path (e.g. the step-back value-call encoders@attr/@js/@urlrender dynamically, byte-identically). A whole-corpus differential gate proves parity. The runtime stays fully dynamic; aHeddle.CSharpTierEnabledtrim switch keeps Roslyn out of a trimmed publish. Ships with theheddleCLI (heddle render <template> --model-json <file>), a T4-successor render tool.Streaming & UTF-8 render surface
New
Generate(data, TextWriter)andGenerate(data, IBufferWriter<byte>)sink overloads with a two-tier, surrogate-safe UTF-8 transcode path — render straight intoResponse.BodyWriterwith no full-string materialization. The string path stays bit-identical; sink paths allocate O(1) regardless of output size (benchmarked). Precompiled templates emit the sink entry points too, with an opt-in"…"u8static-piece fast path.Render budgets
Optional
TemplateOptions.RenderBudgetsets per-render resource caps for running untrusted templates —MaxOutputChars,MaxRenderOps, andMaxRenderTime— and a breach throwsTemplateRenderBudgetExceptioncarryingKind/Limit/Observed. Default is unlimited with zero render-path cost; enforcement lives at the renderer seam, so counts are uniform across the string/TextWriter/IBufferWritersinks and identical on the dynamic and precompiled backends.Demo, samples & docs
A progressively-enhanced in-browser demo (Ace editor + typed WASM language worker + sandboxed render pane) on the published docs site, backed by a trimmed Roslyn-pure WebAssembly host and a Playwright smoke suite. A gallery of ten runnable, golden-asserted samples (SSR, streaming SSR, sandboxed templates, HTML-safe output, component props/slots, custom extensions, definition libraries, dynamic models, build-time codegen, precompiled apps) doubling as end-to-end CI coverage, plus a traceability artifact mapping success criteria to the tests that prove them.
Migration (2.0 breaking changes)
Coming from 1.x, three changes need attention, absorbed as one migration:
Text→Html— the unnamed@(...)now HTML-encodes. Opt out per output with@raw, or restore per template withOutputProfile.Text.TrimDirectiveLinesdefault-on — whole-line directives swallow their trailing newline. SetTrimDirectiveLines = falseto restore 1.x behavior.@import()removed — any@importcall site now fails to compile with a positionedHED4003error; use@<<{{ path }}to share definitions/layouts, or@partial(){{ name }}to embed another template's rendered output inline.Everything else is additive — including the pluggable
Encoder(default preserves existing bytes), the@attr/@js/@urlcontext-encoders, and render budgets.TemplateOptions.AllowCSharpis deprecated in favour ofExpressionModebut keeps working as a bridge. Precompiled projects must be rebuilt with the 2.0Heddle.Generator; 1.x manifests are rejected by the engine-version gate and fall back (or throw underPrecompiledMismatchPolicy.Strict).CI & packaging
Cross-platform test, workflow, and packaging failures resolved: RID-specific tool packing, LF-pinned golden fixtures, serialized multi-TFM runs (fixing a process-global singleton race), culture-pinned formatter tests, explicit .NET runtime installs, project-level symbol-package config, the VS Code extension TypeScript build, a trimmed-runtime string-op fallback surfaced by the WASM demo, and a warning-clean multi-TFM build. Contributor spec/roadmap material is excluded from the published docs site.