Commit Graph
207 Commits
Author SHA1 Message Date
Jen BaschandVinayak 3d03a47933 Revert "Revert "Reject abstract members in non-abstract classes" (#1688)" (#1780)
This reverts commit 1bf00b84ea.

Co-authored-by: Vinayak <vinayak@vama.app>
2026-07-16 11:34:20 -07:00
Jen Basch 71948d69c4 Upgrade to GraalVM 25.1.3, drop macOS Intel builds (#1769) 2026-07-13 15:52:02 -07:00
Daniel Chao 60b0d86b5f Fix eval -x of local members (#1760)
This fixes a regression where local members cannot be seen by the
expression evaluator.

Because variable are now parse-time resolved, this builds a truffle node
by first constructing a synthetic module of all defined local members,
and calls AstBuilder on this synthetic module first.
2026-07-11 00:03:15 +00:00
Daniel Chao 010d971af0 Add tests for empty IntSeq iteration (#1739) 2026-07-08 06:37:56 -07:00
Daniel Chao bd83e29641 Normalize asset paths in local dependencies (#1737)
This changes local asset path resolution so that `..` segments at the
dependency root just resolves to the dependency root.

This makes import resolution work the same between local and remote dependencies.
2026-07-08 05:43:36 -07:00
Daniel Chao 2ec62c99a7 Enforce stricter rules on reference access (#1718)
This changes the following:

1. If given a union type, the member must exist on each member of that type
2. If accessing a member off `Reference<D, Null>`, give a `Reference<D, Null>`

Also:
* Improve error messages thrown during member access.
* Add test around accessing members off of a function type
2026-07-06 19:24:14 -07:00
Daniel Chao eaf73af247 Improve thread safety for pkl:base (#1719)
Stdlib modules are singletons that are shared across multiple evaluators.
This improves thread safety by evaluating its `output.bytes` during
initialization, which initializes truffle nodes (e.g. TypeTestNode),
and also initializes the member cache of the module output of `pkl:base`
2026-07-06 11:19:29 -07:00
Daniel Chao 2ec83198f5 Fix replacements of types nested within nested constraints (#1731)
Also, adjust tests
2026-07-06 08:58:56 -07:00
Jen Basch 6a4d3acf21 Fix incorrect isNoopTypeCheck() calls (#1717)
`isNoopTypeCheck()` is not reliable when inside a TypeNode's constructor. This defers these calls to node execution time.
2026-07-02 14:24:55 -07:00
adityabagchi24andDaniel Chao 1c1a39e37f Fix type argument lost in constraint expressions within generic typealiases (#1709)
Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
2026-07-01 10:10:03 -07:00
Jen Basch 70fc1d4ba3 Correctly handle type aliases with a type variable as the root (#1714) 2026-06-30 06:49:21 +00:00
Daniel Chao 742a8e88da Fix for-generator variable resolution in nested eager scope (#1706)
Fixes an issue around resolving for-generator variables in some cases
2026-06-29 09:07:51 -07:00
Islon Scherer 6239981869 Improve error message for aliased references (#1695) 2026-06-29 18:06:34 +02:00
Daniel Chao f61a5cf541 Check if receiver is a module object in relativePathTo (#1650)
Closes #1649
2026-06-24 11:48:57 +02:00
Islon Scherer dd6939ab3f Add equals and hashcode to PType (#1691) 2026-06-24 11:31:11 +02:00
Daniel Chao 1bf00b84ea Revert "Reject abstract members in non-abstract classes" (#1688)
The changes made in this commit are good, but we're going to kick this out
to the next release.
This is because:

1. There's a couple more issues around the `abstract` modifier that is not
implemented yet, and need design considerations
2. These are breaking changes, and we want to minimize the amount of breakages
for users.
3. The main branch is still the develop branch for Pkl 0.32

We will apply a re-revert of this commit after Pkl 0.32 is released.
2026-06-23 09:46:14 -07:00
Daniel Chao 15f089b275 Implement toString() on VmReference (#1692)
This is still needed right now, because some methods call through to
`toString()`.
2026-06-23 09:45:13 -07:00
Jen Basch 8a43e51e6b SPICE-0020: Deferred, type-safe references (#1354) 2026-06-23 15:26:06 +02:00
Islon Scherer bfac0d66ed Reject relative package URIs (#1683) 2026-06-17 15:39:03 +02:00
Aditya Singh a9c98e4396 Fix incorrect Facts in pkl:base doc comments (#1669)
Several `Facts:` examples in the `pkl:base` standard library docs assert
statements that are false when evaluated. Since these examples are not
run by any test, the mistakes went unnoticed and are rendered verbatim
into the generated API docs, where they mislead readers.

The corrected examples:

- `String.isNotBlank`: `"\t\n\r".isNotBlank` was listed as holding, but
a string of only whitespace is blank, so it is false. Negated it to
match the neighboring `!"".isNotBlank` and `!" ".isNotBlank` examples.
- `DataSize.toBinaryUnit` / `toDecimalUnit`: the `mb`/`mib` lines
mirrored the `kb`/`kib` lines, but the identity only holds for adjacent
units. `1024.kb == 1000.kib` (both 1,024,000 b), whereas `1024.mb` is
1,024,000,000 b and `1000.mib` is 1,048,576,000 b, so they are not
equal. There is no clean round-number equivalent at this magnitude, so I
removed the two false lines; the remaining examples still demonstrate
the conversion.
- `Collection.any`: `!List(1, 2, 3).any((n) -> n.isEven)` is false
because 2 is even. Changed the list to `List(1, 3, 5)` so the negation
holds.
- `IntSeq.end`: the example read `IntSeq(2, 5).start == 5`, which
documents the wrong property and is false (`start` is 2). Corrected it
to `IntSeq(2, 5).end == 5`.
- `List.isDistinctBy` / `distinctBy`: `List("a", "b", "abc")` is not
distinct by length, since `"a"` and `"b"` both have length 1. Switched
to `List("a", "bb", "ccc")` so the distinctness examples hold.
- `Map`: `Map(...).values` returns a `List`, not a `Set`. Corrected the
expected type.

I verified that each corrected example evaluates to `true`, and that the
neighboring examples I kept still pass, using the released Pkl 0.31.1
binary. The changes are confined to doc-comment text, so formatting is
unaffected.

---------

Signed-off-by: Aditya Singh <adisin650@gmail.com>
2026-06-11 17:10:14 +00:00
Daniel Chao 84d2c32d10 Improve handling of frame slots (#1634)
This makes various improvements to the handling of frame slot vars, and
includes some bug fixes introduced by
https://github.com/apple/pkl/pull/1622

* Refactor SymbolTable to track for-generator and parameter slots in
each scope
* Execute let expressions in their own root node in some places
* Unify how frame slots are managed; they are all represented as
`FrameSlotVariable`, created in `AstBuilder`, and passed into
`SymbolTable`.
* Fix how let expressions are executed in custom this scopes (introduce
a new root node when needed)
2026-06-11 03:02:42 +00:00
Daniel Chao 27fe06c796 Fix errors around strings with lone high or low surrogates (#1673)
This fixes some errors around treatment of strings with lone high/low
surrogates.
2026-06-10 08:35:22 -07:00
Daniel Chao 1a1e1cfea9 Fix String.padStart/padEnd (#1672)
Fixes the following two bugs:

* Pads to incorrect string length
* Does not append full code point
2026-06-10 08:34:50 -07:00
ce0383837a Reject abstract members in non-abstract classes (#1647)
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>
2026-06-10 10:36:40 +02:00
Daniel Chao 391329c1fa Fix test (#1667)
The previous PR (https://github.com/apple/pkl/pull/1637) got auto-merged
by mistake; there's a failing test here
2026-06-08 16:11:49 -05:00
Daniel ChaoandIslon Scherer d012285f7d Improve HTTP redirect following (#1637)
This implements HTTP redirect following ourselves.

The goal is:

1. All I/O is checked against `--allowed-resources` and
`--allowed-modules`, including HTTP redirects
2. HTTP rewrite rules can affect redirect following
3. HTTP headers can affect redirect following

---------

Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2026-06-08 18:13:48 +00:00
Daniel Chao 01f8fcae7b Catch correct exception type in MultiplicationNode (#1652)
Closes #1651
2026-06-05 12:55:27 -07:00
Daniel Chao 41e012a0f0 Fix toRadixString on math.minInt (#1656)
Closes #1655
2026-06-05 18:27:03 +00:00
Daniel Chao aa01241068 Fix eager typecheck of Map (#1654)
Closes #1653
2026-06-05 11:24:00 -07:00
Jen Basch 74eae0388e Fix error rendering @ConvertProperty annotations during error reporting (#1648)
The added snippet test originally produced error "A value of type
`Function2` cannot be exported."

This PR actually fixes the bug twice:
* By marking `ConvertProperty.render` as `hidden` so that it is skipped
when the enclosing object is exported. This broke any attempts to obtain
the module schema because this requires exporting all annotations on all
class properties.
* By changing the way that `VmUndefinedValueException.fillInHint()`
obtains the module URI to avoid obtaining the module schema (and
triggering the more expensive module schema generation process).

It also makes function-typed annotation properties in `pkl:Command` hidden to avoid similar issues there.
2026-06-05 16:50:34 +00:00
Jen Basch 68f7d06eed Improve error message when parsing truncated let expressions (#1639)
This previously yielded
```
Unexpected token `}`. Expected `}`.
```
Pretty confusing, no?

Now it's just
```
Unexpected token `}`.
```

Resolves #1638
2026-06-02 16:00:46 -07:00
Daniel Chao 035ef0a789 Change loading of external readers (#1394)
This introduces breaking changes for external readers are loaded:

1. In PklProject, relative paths are resolved relative to the enclosing
PklProject file (make behavior consistent with how other settings work)
2. Make CLI flags blow away any settings set on a PklProject
3. Introduce a new `workingDir` property, which defaults to the
PklProject dir

The overall goal is to make this behavior consistent with how other
settings work.
For example, relative paths for other evaluator settings are already
relative to the project directory.
Additionally, in every other case, CLI flags will overwrite any setting
set within PklProject.
2026-06-02 18:02:52 +00:00
Daniel Chao c9f3823952 Touch ups around local members (#1633)
* Add assertion if ObjectMember key in cachedValues is not local (should never happen)
* Move test to snippet tests
2026-06-02 03:47:46 +00:00
Jen Basch 18af04c2ec Correctly count regular members of Dynamic (#1632)
Previously, `VmDynamic.isHiddenOrLocalProperty` didn't correctly
identify locals whose cache key is an `ObjectMember` instead of an
`Identifier`, causing `VmDynamic. getRegularMemberCount` to return an
incorrect value. This caused some renderers to produce incorrect output.

Resolves #1631
2026-06-01 20:27:19 -07:00
Daniel Chao 7dd2bc67de Optimize let expressions as frame slot vars (#1622)
This introduces an optimization to write let expressions to frame slots
of the current frame, rather than transforming them into lambdas. As a
result, let expressions are _much_ faster to execute.
2026-06-01 16:53:30 -07:00
Islon Scherer bfda4cc8c8 Fix forcing of VmValue during error rendering (#1629) 2026-06-01 18:25:33 +02:00
Islon Scherer dbf04f6598 Resolve variables at parse time (#1429)
This replaces `ResolveVariableNode` and `ResolveMethodNode` with their resolution.
When we build the truffle node tree, we determine whether names resolve to:

* lexical scope
* base module
* implicit this

Then, we use this information to directly construct the underlying nodes (`ReadPropertyNode`, `ReadLocalPropertyNode`, etc).

Additionally, `AstBuilder` determines whether the property access must be const or not.

This introduces a `BaseModuleMembers` registry, which gets generated as part of Java compilation.
2026-05-26 14:08:20 -07:00
Mirko Alicastro ff319faef3 Use Locale.ROOT when lowercasing rewrite URIs (#1618)
Use Locale.ROOT to apply the lowecase format. For URI scheme and host
locale-neutral casing is the semantically the correct choice. Added a
unit test that sets the default locale to tr-TR and that would fail
without the fix.
2026-05-26 09:37:42 -07:00
Daniel Chao b070d56741 Remove public modifier on LazyHttpClient and RequestRewritingClient (#1609)
This introduces a test helper to expose configured HTTP settings, and
makes the underlying classes package-private again.
2026-05-22 10:17:26 -07:00
Daniel Chao 8e2e5e4ba8 Improve HTTP headers logic (#1584)
* Relax forbidden headers constraints
  - remove restriction on browser-related headers
- allow any glob pattern (no need to end with `/` or `*`, because glob
patterns already require users to explicitly declare prefix matches if
that's the intention)
* Replace `List<Pair<, ...>>`; use `Map<String, ...>` instead
* Use glob pattern strings as an API throughout, instead of `Pattern`
(e.g. in `HttpClientBuilder`)
* Add HTTP headers to message passing API
* Add HTTP headers to executor API (introduces `ExecutorSpiOptions4`)
* Add tests for Gradle, CLI, and pkl-executor invocations
* Improve documentation
* Add `isGlobPattern` API to class `String` for in-language validation
of http headers
* Behavior change: make sure explicitly configured `User-Agent` in
`HttpClientBuilder` can be shadowed by headers (allows users to set
`--http-header "**=User-Agent: My User Agent"` and for this to be the
only user agent).

CC @kyokuping
2026-05-21 20:07:06 -07:00
odenix 3dc93cbd4a pkl-core: Migrate nullness to JSpecify (#1601)
Replace pkl-core's local nullness annotations with JSpecify annotations.
Enable NullAway checking for pkl-core packages except org.pkl.core.ast
and org.pkl.core.stdlib.

Notable code changes:
- Add a dedicated late-init constructor to VmTyped
- Move VmExceptionBuilder's fallback message derivation from withCause()
to build()
- Split VmException rendering between builder-provided messages and
string-backed messages
- Initialize MessageTransport handlers with default throwing handlers
- Update JSON helper collection types to allow nullable values JSON
arrays and objects can contain JSON null,
so the Java Map/List element types need to model nullable elements
explicitly
- Make public command transform APIs accept nullable transformed values 
   Command transforms can produce null for optional/default handling,
so the BiFunction and options-map element types now model that
explicitly
- Make ExecutorSpiException accept nullable message and cause 
Existing call sites can pass nullable causes from Throwable.getCause()
- Remove JSR-305 semantics from `@LateInit`
   JSpecify does not support the same type-qualifier-nickname pattern,
so `@LateInit` is now documentation plus a NullAway
constructor-initialization exemption

Out of scope:
- NullAway checking of org.pkl.core.ast and org.pkl.core.stdlib
- IntelliJ warnings related to `@LateInit` fields
- Removing the JSR-305 dependency, since concurrency annotations are
still in use
2026-05-21 13:57:20 -07:00
Islon Scherer 3fbcd463e0 Introduce "minimal" test reporter (#1563) 2026-05-19 17:20:26 +02:00
Daniel Chao a7a64acbac Improve handling of evaling dependency notation URIs (#1595) 2026-05-15 15:51:09 -07:00
Daniel Chao 3ad1cb3645 Ensure local dependency matches PklProject.dep.json version (#1594)
The version of local project dependencies should _always_ exactly match
up with what's declared in a PklProject.deps.json; any package in the
transitive dependency tree should always be delcaring the same import
too.

Closes #1591
2026-05-15 11:48:57 -07:00
14085c18bb Add support for customizing HTTP headers (#1196)
This PR adds support for custom HTTP headers, introducing a
`--http-header` CLI flag to accept `key=value` pairs. These headers can
also be specified within the `setting.pkl` file.

Closes #633

SPICE: https://github.com/apple/pkl-evolution/pull/24

---------

Co-authored-by: Jen Basch <jbasch94@gmail.com>
Co-authored-by: Islon Scherer <islonscherer@gmail.com>
2026-05-12 13:53:59 -07:00
Daniel Chao 38733e5781 Fix parsing of dependency notation URIs (#1570)
Fixes a thrown exception when path segments contain characters that
aren't URI safe (e.g. `import "@foo/bar baz.pkl"`).

Closes #1545
2026-05-07 13:00:52 -07:00
Jen Basch b7ba6a8649 Fix pkl:test fact power assertions when member source section is unavailable (#1571)
Power assertions only work when the source section is available. If it
is unavailable, power assertions throw a ParserError (unexpected EOF on
an empty input) when re-parsing the expression for presentation.
2026-05-04 12:25:15 -07:00
Daniel Chao 2b3603b544 Reformat Kotlin code (#1560)
ktfmt has much improved how it formats Kotlin code. Unfortunately, this
means that whenever we touch a single line in a Kotlin file, we get a
_lot_ more changes thanks to ratcheting now picking up this file for
formatting.

This PR just reformats every single Kotlin file so we don't have to deal
with this churn in future PRs that touch Kotlin code.
2026-04-25 06:14:44 -07:00
Jen Basch e07abb7311 SPICE-0028: Add support for multi-line string line continuations (#1507)
SPICE: https://github.com/apple/pkl-evolution/pull/31
2026-04-21 10:29:52 -07:00
Jen Basch eeb0970dc4 Fix bug where reusing a pklbinary#Renderer could result in incorrect output (#1525) 2026-04-15 23:12:36 -07:00