9.2 KiB
Changelog
Unreleased
-
Language: Abstract Classes and Interfaces
- Support for
abstractmodifier on classes, methods, and variables. - Introduced
interfaceas a synonym forabstract class, supporting full state (constructors, fields,initblocks) and implementation by parts via MI. - New
closedmodifier (antonym toopen) to prevent overriding class members. - Refined
overridelogic: mandatory keyword when re-declaring members that exist in the ancestor chain (MRO). - MI Satisfaction: Abstract requirements are automatically satisfied by matching concrete members found later in the C3 MRO chain without requiring explicit proxy methods.
- Integration: Updated highlighters (lynglib, lyngweb, IDEA plugin), IDEA completion, and Grazie grammar checking.
- Documentation: Updated
docs/OOP.mdwith sections on "Abstract Classes and Members", "Interfaces", and "Overriding and Virtual Dispatch".
- Support for
-
Language: Class properties with accessors
- Support for
val(read-only) andvar(read-write) properties in classes. - Syntax:
val name [ : Type ] get() { body }orvar name [ : Type ] get() { body } set(value) { body }. - Laconic Expression Shorthand:
val prop get() = expressionandvar prop get() = read set(v) = write. - Properties are pure accessors and do not have automatic backing fields.
- Validation:
varproperties must have both accessors;valmust have only a getter. - Integration: Updated TextMate grammar and IntelliJ plugin (highlighting + keywords).
- Documentation: New "Properties" section in
docs/OOP.md.
- Support for
-
Language: Restricted Setter Visibility
- Support for
private setandprotected setmodifiers onvarfields and properties. - Allows members to be publicly readable but only writable from within the declaring class or its subclasses.
- Enforcement at runtime: throws
AccessExceptionon unauthorized writes. - Supported only for declarations in class bodies (fields and properties).
- Documentation: New "Restricted Setter Visibility" section in
docs/OOP.md.
- Support for
-
Language: Late-initialized
valfields in classes- Support for declaring
valwithout an immediate initializer in class bodies. - Compulsory initialization: every late-init
valmust be assigned at least once within the class body or aninitblock. - Write-once enforcement: assigning to a
valis allowed only if its current value isUnset. - Access protection: reading a late-init
valbefore it is assigned returns theUnsetsingleton; usingUnsetfor most operations throws anUnsetException. - Extension properties do not support late-init.
- Documentation: New "Late-initialized
valfields" and "TheUnsetsingleton" sections indocs/OOP.md.
- Support for declaring
-
Docs: OOP improvements
- New page:
docs/scopes_and_closures.mddetailingClosureScoperesolution order, recursion‑safe helpers (chainLookupIgnoreClosure,chainLookupWithMembers,baseGetIgnoreClosure), cycle prevention, and capturing lexical environments for callbacks (snapshotForClosure). - Updated:
docs/advanced_topics.md(link to the new page),docs/parallelism.md(closures inlaunch/flow),docs/OOP.md(visibility from closures with preservedcurrentClassCtx),docs/exceptions_handling.md(compatibility aliasSymbolNotFound). - Tutorial: added quick link to Scopes and Closures.
- New page:
-
IDEA plugin: Lightweight autocompletion (experimental)
- Global completion: local declarations, in‑scope parameters, imported modules, and stdlib symbols.
- Member completion: after a dot, suggests only members of the inferred receiver type (incl. chained calls like
Path(".." ).lines().→Iteratormethods). No global identifiers appear after a dot. - Inheritance-aware: direct class members first, then inherited (e.g.,
ListincludesCollection/Iterablemethods). - Heuristics: handles literals (
"…"→String, numbers →Int/Real,[...]→List,{...}→Dict) and staticNamespace.members. - Performance: capped results, early prefix filtering, per‑document MiniAst cache, cancellation checks.
- Toggle: Settings | Lyng Formatter → "Enable Lyng autocompletion (experimental)" (default ON).
- Stabilization: DEBUG completion/Quick Doc logs are OFF by default; behavior aligned between IDE and isolated engine tests.
-
Language: Named arguments and named splats
- New call-site syntax for named arguments using colon:
name: value.- Positional arguments must come before named; positionals after a named argument inside parentheses are rejected.
- Trailing-lambda interaction: if the last parameter is already assigned by name (or via a named splat), a trailing
{ ... }block is illegal.
- Named splats:
...can now expand a Map into named arguments.- Only string keys are allowed; non-string keys raise a clear error.
- Duplicate assignment across named args and named splats is an error.
- Ellipsis (variadic) parameters remain positional-only and cannot be named.
- Rationale:
=is assignment and an expression in Lyng;:at call sites avoids ambiguity. Declarations keepname: Type; call-site casts continue to useas/as?. - Documentation updated: proposals and declaring-arguments sections now cover named args/splats and error cases.
- Tests added covering success cases and errors for named args/splats and trailing-lambda interactions.
- New call-site syntax for named arguments using colon:
-
Tooling: Highlighters and TextMate bundle updated for named args
- Website/editor highlighter (lyngweb + site) works with
name: valueand...Map("k" => v); added JS tests covering punctuation/operator spans for:and.... - TextMate grammar updated to recognize named call arguments:
name: valueafter(or,withnamehighlighted asvariable.parameter.named.lyngand:as punctuation; excludes::. - TextMate bundle version bumped to 0.0.3; README updated with details and guidance.
- Website/editor highlighter (lyngweb + site) works with
-
Multiple Inheritance (MI) completed and enabled by default:
- Active C3 Method Resolution Order (MRO) for deterministic, monotonic lookup across complex hierarchies and diamonds.
- Qualified dispatch:
this@Type.member(...)inside class bodies starts lookup at the specified ancestor.- Cast-based disambiguation:
(expr as Type).member(...),(expr as? Type)?.member(...)(works with existing safe-call?.).
- Field inheritance (
val/var) under MI:- Instance storage is disambiguated per declaring class; unqualified read/write resolves to the first match in MRO.
- Qualified read/write targets the chosen ancestor’s storage.
- Constructors and initialization:
- Direct bases are initialized left-to-right; each ancestor is initialized at most once (diamond-safe de-duplication).
- Header-specified constructor arguments are passed to direct bases.
- Visibility enforcement under MI:
privatevisible only inside the declaring class body.protectedvisible inside the declaring class and any of its transitive subclasses; unrelated contexts cannot access it (qualification/casts do not bypass).
- Diagnostics improvements:
- Missing member/field messages include receiver class and linearization order; hints for
this@Typeor casts when helpful. - Invalid
this@Typereports that the qualifier is not an ancestor and shows the receiver lineage. as/as?cast errors include actual and target type names.
- Missing member/field messages include receiver class and linearization order; hints for
-
Documentation updated (docs/OOP.md and tutorial quick-start) to reflect MI with active C3 MRO.
Notes:
- Existing single-inheritance code continues to work; resolution reduces to the single base.
- If code previously relied on non-deterministic parent set iteration, C3 MRO provides a predictable order; disambiguate explicitly if needed using
this@Type/casts.
Changelog
All notable changes to this project will be documented in this file.
Unreleased
-
CLI: Added
fmtas a first-class Clikt subcommand.- Default behavior: formats files to stdout (no in-place edits by default).
- Options:
--check: check only; print files that would change; exit with code 2 if any changes are needed.-i, --in-place: write formatted result back to files.--spacing: apply spacing normalization.--wrap,--wrapping: enable line wrapping.
- Mutually exclusive:
--checkand--in-placetogether now produce an error and exit with code 1. - Multi-file stdout prints headers
--- <path> ---per file. lyng --helpshowsfmt;lyng fmt --helpdisplays dedicated help.- Fix: Property accessors (
get,set,private set,protected set) are now correctly indented relative to the property declaration. - Fix: Indentation now correctly carries over into blocks that start on extra‑indented lines (e.g., nested
ifstatements or property accessor bodies). - Fix: Formatting Markdown files no longer deletes content in
.lyngcode fences and works correctly with injected files (resolves clobbering,StringIndexOutOfBoundsException, andnonempty text is not covered by blockerrors).
-
CLI: Preserved legacy script invocation fast-paths:
lyng script.lyng [args...]executes the script directly.lyng -- -file.lyng [args...]executes a script whose name begins with-.
-
CLI: Fixed a regression where the root help banner could print before subcommands.
- Root command no longer prints help when a subcommand (e.g.,
fmt) is invoked.
- Root command no longer prints help when a subcommand (e.g.,