Add nested declarations and lifted enums
This commit is contained in:
1 parent
c35efdc2ae
commit
3b290116b8
11 files changed
+541
-110
No files matched your search
+42
@@ -113,6 +113,48 @@ val handler = object {
|
||||
- **Serialization**: Anonymous objects are **not serializable**. Attempting to encode an anonymous object via `Lynon` will throw a `SerializationException`. This is because their class definition is transient and cannot be safely restored in a different session or process.
|
||||
- **Type Identity**: Every object expression creates a unique anonymous class. Two identical object expressions will result in two different classes with distinct type identities.
|
||||
|
||||
## Nested Declarations
|
||||
|
||||
Lyng allows classes, objects, enums, and type aliases to be declared inside another class. These declarations live in the **class namespace** (not the instance), so they do not capture an outer instance and are accessed with a qualifier.
|
||||
|
||||
```lyng
|
||||
class A {
|
||||
class B(x?)
|
||||
object Inner { val foo = "bar" }
|
||||
type Alias = B
|
||||
enum E { One, Two }
|
||||
}
|
||||
|
||||
val ab = A.B()
|
||||
assertEquals(ab.x, null)
|
||||
assertEquals(A.Inner.foo, "bar")
|
||||
```
|
||||
|
||||
Rules:
|
||||
- **Qualified access**: use `Outer.Inner` for nested classes/objects/enums/aliases. Inside `Outer` you can refer to them by unqualified name unless shadowed.
|
||||
- **No inner semantics**: nested declarations do not capture an instance of the outer class. They are resolved at compile time.
|
||||
- **Visibility**: `private` restricts a nested declaration to the declaring class body (not visible from outside or subclasses).
|
||||
- **Reflection name**: a nested class reports `Outer.Inner` (e.g., `A.B::class.name` is `"A.B"`).
|
||||
- **Type aliases**: behave as aliases of the qualified nested type and are expanded by the type system.
|
||||
|
||||
### Lifted Enum Entries
|
||||
|
||||
Enums can optionally lift their entries into the surrounding class namespace using `*`:
|
||||
|
||||
```lyng
|
||||
class A {
|
||||
enum E* { One, Two }
|
||||
}
|
||||
|
||||
assertEquals(A.One, A.E.One)
|
||||
assertEquals(A.Two, A.E.Two)
|
||||
```
|
||||
|
||||
Notes:
|
||||
- `E*` exposes entries in `A` as if they were direct members (`A.One`).
|
||||
- If a name would conflict with an existing class member, compilation fails (no implicit fallback).
|
||||
- Without `*`, use the normal `A.E.One` form.
|
||||
|
||||
## Properties
|
||||
|
||||
Properties allow you to define member accessors that look like fields but execute code when read or written. Unlike regular fields, properties in Lyng do **not** have automatic backing fields; they are pure accessors.
|
||||
|
||||
@@ -107,6 +107,23 @@ Singleton objects are declared using the `object` keyword. They define a class a
|
||||
|
||||
Logger.log("Hello singleton!")
|
||||
|
||||
## Nested Declarations (short)
|
||||
|
||||
Classes, objects, and enums can be declared inside another class. They live in the class namespace (no outer instance capture), so you access them with a qualifier:
|
||||
|
||||
class A {
|
||||
class B(x?)
|
||||
object Inner { val foo = "bar" }
|
||||
enum E* { One, Two }
|
||||
}
|
||||
|
||||
val ab = A.B()
|
||||
assertEquals(ab.x, null)
|
||||
assertEquals(A.Inner.foo, "bar")
|
||||
assertEquals(A.One, A.E.One)
|
||||
|
||||
See [OOP notes](OOP.md#nested-declarations) for rules, visibility, and enum lifting details.
|
||||
|
||||
## Delegation (briefly)
|
||||
|
||||
You can delegate properties and functions to other objects using the `by` keyword. This is perfect for patterns like `lazy` initialization.
|
||||
|
||||
@@ -108,6 +108,24 @@ object Config {
|
||||
Config.show()
|
||||
```
|
||||
|
||||
### Nested Declarations and Lifted Enums
|
||||
You can now declare classes, objects, enums, and type aliases inside another class. These nested declarations live in the class namespace (no outer instance capture) and are accessed with a qualifier.
|
||||
|
||||
```lyng
|
||||
class A {
|
||||
class B(x?)
|
||||
object Inner { val foo = "bar" }
|
||||
enum E* { One, Two }
|
||||
}
|
||||
|
||||
val ab = A.B()
|
||||
assertEquals(ab.x, null)
|
||||
assertEquals(A.Inner.foo, "bar")
|
||||
assertEquals(A.One, A.E.One)
|
||||
```
|
||||
|
||||
The `*` on `enum E*` lifts entries into the enclosing class namespace (compile-time error on ambiguity).
|
||||
|
||||
### Object Expressions
|
||||
You can now create anonymous objects that inherit from classes or interfaces using the `object : Base { ... }` syntax. These expressions capture their lexical scope and support multiple inheritance.
|
||||
|
||||
|
||||
Reference in new issue
Block a user