mirror of
https://github.com/apple/pkl.git
synced 2026-06-11 08:12:50 +02:00
ce0383837a
Fixes #1614. ## Context A non-abstract `class` (or `module`) was allowed to declare `abstract` properties and methods. Because such an enclosing type is instantiable, an `abstract` member there can never be guaranteed an implementation — so the contradiction surfaced only as a runtime error when the member was accessed (`Cannot invoke abstract method`), or not at all. This makes it a compile-time error to declare an `abstract` member unless its enclosing class or module is also `abstract`. This is consistent with how Pkl already rejects instantiating an abstract class, and mirrors how Java and Kotlin treat abstract members. ## Before ```pkl class Foo { abstract bar: Int } res = new Foo { bar = 5 } // evaluated successfully (should fail) ``` ```pkl class Foo { abstract function bar(): Int } res = new Foo {} // evaluated successfully; res.bar() failed only at runtime ``` ## After ``` –– Pkl Error –– Cannot define an abstract member in a non-abstract class. 2 | abstract bar: Int ^^^^^^^^ at Foo A member can only be `abstract` if its enclosing class is also `abstract`. ``` ## Implementation - `AstBuilder` now validates, while building the AST, that a non-abstract class/module declares no `abstract` members. The check runs in both `visitClass` and `visitModule`, and the error points at the `abstract` keyword. - Adds the `abstractMemberInNonAbstractClass` error message. ## Scope: classes and modules The issue describes classes; I applied the same rule to modules as well, since a module is a class in Pkl and a non-abstract module is likewise directly evaluatable. Happy to narrow this to classes only if you'd prefer — it's a one-line change either way. The `moduleMethodModifiers` pkl-doc test fixture declared an abstract method at non-abstract module level (relying on the old behavior); it's updated to an `abstract module`, and its expected documentation output is regenerated. ## Tests - New `LanguageSnippetTests` error cases: abstract property in a class, abstract method in a class, and abstract member in a module. - `./gradlew build` passes (`pkl-core` and `pkl-doc` included). --------- Co-authored-by: Vinayak <vinayak@vama.app> Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
Core implementation of the Pkl language. Includes Java APIs for embedding the language into JVM applications, and for building libraries and tools on top of the language.