diff --git a/pkl-core/src/main/java/org/pkl/core/ast/builder/SymbolTable.java b/pkl-core/src/main/java/org/pkl/core/ast/builder/SymbolTable.java index 507b2593d..b73976ab2 100644 --- a/pkl-core/src/main/java/org/pkl/core/ast/builder/SymbolTable.java +++ b/pkl-core/src/main/java/org/pkl/core/ast/builder/SymbolTable.java @@ -386,7 +386,7 @@ public final class SymbolTable { || value instanceof Boolean || value instanceof VmDuration || value instanceof VmDataSize) { - return "[" + value + "]"; + return "[" + VmUtils.toPklString(value) + "]"; } } diff --git a/pkl-core/src/main/java/org/pkl/core/ast/internal/ToStringNode.java b/pkl-core/src/main/java/org/pkl/core/ast/internal/ToStringNode.java index 2757e3603..7af13a07f 100644 --- a/pkl-core/src/main/java/org/pkl/core/ast/internal/ToStringNode.java +++ b/pkl-core/src/main/java/org/pkl/core/ast/internal/ToStringNode.java @@ -17,7 +17,6 @@ package org.pkl.core.ast.internal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.DirectCallNode; @@ -75,11 +74,10 @@ public abstract class ToStringNode extends UnaryExpressionNode { return (String) callNode.call(value, value.getVmClass().getPrototype()); } - @Fallback - @Override + @Specialization @TruffleBoundary - protected Object fallback(Object value) { - return value.toString(); + protected String evalVmValue(VmValue value) { + return value.toPklString(); } protected InvokeMethodVirtualNode createInvokeNode() { diff --git a/pkl-core/src/main/java/org/pkl/core/ast/type/VmTypeMismatchException.java b/pkl-core/src/main/java/org/pkl/core/ast/type/VmTypeMismatchException.java index deeab0f34..c2dae38cc 100644 --- a/pkl-core/src/main/java/org/pkl/core/ast/type/VmTypeMismatchException.java +++ b/pkl-core/src/main/java/org/pkl/core/ast/type/VmTypeMismatchException.java @@ -119,7 +119,7 @@ public abstract class VmTypeMismatchException extends ControlFlowException { .map((l) -> valueFormatter.formatStringValue(l, "")) .collect(Collectors.joining("|")); } else { - renderedType = expectedType.toString(); + renderedType = VmUtils.toPklString(expectedType); } if (actualValue instanceof VmNull @@ -156,7 +156,10 @@ public abstract class VmTypeMismatchException extends ControlFlowException { builder .append( ErrorMessages.createIndented( - "typeMismatch", indent, renderedType, VmUtils.getClass(actualValue))) + "typeMismatch", + indent, + renderedType, + VmUtils.getClass(actualValue).toPklString())) .append("\n") .append(indent) .append("Value: ") @@ -177,7 +180,7 @@ public abstract class VmTypeMismatchException extends ControlFlowException { public ClassType(SourceSection sourceSection, VmClass actualClass, VmClass expectedClass) { super(sourceSection, actualClass); this.expectedClass = expectedClass; - renderedExpected = "Class<" + expectedClass + ">"; + renderedExpected = "Class<" + expectedClass.toPklString() + ">"; } public ClassType(SourceSection sourceSection, VmClass actualClass, PType expectedType) { @@ -191,7 +194,7 @@ public abstract class VmTypeMismatchException extends ControlFlowException { public void buildMessage( AnsiStringBuilder builder, String indent, boolean withPowerAssertions) { var actualClass = (VmClass) actualValue; - var renderedActualClass = "Class<" + actualClass + ">"; + var renderedActualClass = "Class<" + actualClass.toPklString() + ">"; // give better error than "expected Class, but got Class" in case of naming // conflict diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmBytes.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmBytes.java index c8c2520b0..b274aa0b5 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmBytes.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmBytes.java @@ -168,7 +168,7 @@ public final class VmBytes extends VmValue implements Iterable { } @Override - public String toString() { + public String toPklString() { var sb = new StringBuilder("Bytes("); var isFirst = true; for (var byt : bytes) { diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java index dc41f0862..05660f413 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java @@ -748,7 +748,7 @@ public final class VmClass extends VmValue { } @Override - public String toString() { + public String toPklString() { return getDisplayName(); } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmCollection.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmCollection.java index 1cc5fce48..1639ba6fd 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmCollection.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmCollection.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -166,17 +166,19 @@ public abstract class VmCollection extends VmValue implements Iterable { var iter = iterator(); var builder = new StringBuilder(); - builder.append(iter.next()); + // TODO: use ToStringNode + builder.append(VmUtils.toPklString(iter.next())); while (iter.hasNext()) { builder.append(separator); - builder.append(iter.next()); + builder.append(VmUtils.toPklString(iter.next())); } return builder.toString(); } - public final String toString() { + @TruffleBoundary + public final String toPklString() { return VmValueRenderer.multiLine(Integer.MAX_VALUE).render(this); } } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmDataSize.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmDataSize.java index 698924ed3..e23760d31 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmDataSize.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmDataSize.java @@ -156,7 +156,7 @@ public final class VmDataSize extends VmValue implements Comparable } @Override - public String toString() { + public String toPklString() { return MathUtils.isMathematicalInteger(value) ? (long) value + "." + unit : value + "." + unit; } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmDuration.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmDuration.java index 010486ef3..99d6d2836 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmDuration.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmDuration.java @@ -15,6 +15,7 @@ */ package org.pkl.core.runtime; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.ValueType; import java.util.*; import org.jspecify.annotations.Nullable; @@ -152,7 +153,8 @@ public final class VmDuration extends VmValue implements Comparable } @Override - public String toString() { + @TruffleBoundary + public String toPklString() { return DurationUtils.toPklString(value, unit); } } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java index 9d352dd26..d38641d30 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java @@ -83,7 +83,7 @@ public final class VmDynamic extends VmObject { iterateAlreadyForcedMemberValues( (key, member, value) -> { - properties.put(key.toString(), VmValue.export(value)); + properties.put(VmUtils.toPklString(key), VmValue.export(value)); return true; }); diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmFunction.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmFunction.java index 7378d7e1b..0a5c988f5 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmFunction.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmFunction.java @@ -199,14 +199,14 @@ public final class VmFunction extends VmObjectLike { return System.identityHashCode(this); } - @Override - @TruffleBoundary - public String toString() { - return VmValueRenderer.singleLine(Integer.MAX_VALUE).render(this); - } - @Override public boolean isParseTimeInvisibleScope() { return isFunctionAmend && !hasObjectParams; } + + @Override + @TruffleBoundary + public String toPklString() { + return VmValueRenderer.singleLine(Integer.MAX_VALUE).render(this); + } } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmIntSeq.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmIntSeq.java index b2b77b149..062834cbd 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmIntSeq.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmIntSeq.java @@ -127,7 +127,7 @@ public final class VmIntSeq extends VmValue implements Iterable { @Override @TruffleBoundary - public String toString() { + public String toPklString() { return step == 1 ? "IntSeq(" + start + ", " + end + ")" : "IntSeq(" + start + ", " + end + ").step(" + step + ")"; diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmMap.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmMap.java index 5721114f4..491ecbcae 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmMap.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmMap.java @@ -286,7 +286,8 @@ public final class VmMap extends VmValue implements Iterable { @Override @TruffleBoundary - public String toString() { + public String toPklString() { force(true); return VmValueRenderer.singleLine(Integer.MAX_VALUE).render(this); } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmReference.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmReference.java index a7de84fbd..76e3c3315 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmReference.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmReference.java @@ -539,7 +539,7 @@ public final class VmReference extends VmValue { // in-language calls _should_ all go through `ToStringNode`. // however, some calls escape through to here currently (e.g. `Listing.join`). @Override - public String toString() { + public String toPklString() { var toStringMethod = getVmClass().getDeclaredMethod(Identifier.TO_STRING); assert toStringMethod != null; var callNode = DirectCallNode.create(toStringMethod.getCallTarget()); diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmRegex.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmRegex.java index 0a17b03f7..84c9e23f4 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmRegex.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmRegex.java @@ -77,7 +77,8 @@ public final class VmRegex extends VmValue { } @Override - public String toString() { + @TruffleBoundary + public String toPklString() { var builder = new StringBuilder(); builder.append("Regex("); ValueFormatter.withCustomStringDelimiters().formatStringValue(pattern.pattern(), "", builder); diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmTypeAlias.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmTypeAlias.java index cf57cc824..23c25e270 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmTypeAlias.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmTypeAlias.java @@ -308,7 +308,7 @@ public final class VmTypeAlias extends VmValue { } @Override - public String toString() { + public String toPklString() { return qualifiedName.startsWith("pkl.base#") ? simpleName : qualifiedName; } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmUndefinedValueException.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmUndefinedValueException.java index 562fcc6b2..ae5ca699a 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmUndefinedValueException.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmUndefinedValueException.java @@ -98,7 +98,7 @@ public final class VmUndefinedValueException extends VmEvalException { } builder.append(Lexer.maybeQuoteIdentifier(pathPart.toString())); } else { - builder.append('[').append(pathPart).append(']'); + builder.append('[').append(VmUtils.toPklString(pathPart)).append(']'); } } } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java index ce3940590..70218c100 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java @@ -1125,6 +1125,18 @@ public final class VmUtils { return value; } + public static String toPklString(Object value) { + if (value instanceof VmValue vmValue) { + return vmValue.toPklString(); + } + return toString(value); + } + + @TruffleBoundary + private static String toString(Object value) { + return value.toString(); + } + public static boolean isPklBug(VmStackOverflowException e) { // There's no good way to tell if a StackOverflowError came from Pkl, or from our // implementation. diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmValue.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmValue.java index 2d1b9d170..909b889a6 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmValue.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmValue.java @@ -15,9 +15,12 @@ */ package org.pkl.core.runtime; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import org.jspecify.annotations.Nullable; public abstract class VmValue { + private final VmValueRenderer vmValueRenderer = VmValueRenderer.multiLine(Integer.MAX_VALUE); + public abstract VmClass getVmClass(); public VmTyped getPrototype() { @@ -90,4 +93,16 @@ public abstract class VmValue { /** Enables calling `vmValue.equals()` when not behind a Truffle boundary. */ @Override public abstract boolean equals(Object obj); + + @TruffleBoundary + public abstract String toPklString(); + + /** + * Override default implementation because it calls {@link #hashCode()}, which will do object eval + * on certain types. + */ + @Override + public final String toString() { + return vmValueRenderer.render(this); + } } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmValueRenderer.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmValueRenderer.java index 4abef27cb..65ebb1c43 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmValueRenderer.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmValueRenderer.java @@ -111,12 +111,12 @@ public final class VmValueRenderer { @Override public void visitDuration(VmDuration value) { - append(value); + append(value.toPklString()); } @Override public void visitDataSize(VmDataSize value) { - append(value); + append(value.toPklString()); } private void renderByteSize(VmDataSize size) { @@ -169,12 +169,12 @@ public final class VmValueRenderer { @Override public void visitRegex(VmRegex value) { - append(value); + append(value.toPklString()); } @Override public void visitIntSeq(VmIntSeq value) { - append(value); + append(value.toPklString()); } @Override @@ -258,12 +258,12 @@ public final class VmValueRenderer { @Override public void visitClass(VmClass value) { - append(value); + append(value.toPklString()); } @Override public void visitTypeAlias(VmTypeAlias value) { - append(value); + append(value.toPklString()); } @Override @@ -296,7 +296,7 @@ public final class VmValueRenderer { } private void append(Object value) { - builder.append(value); + builder.append(VmUtils.toPklString(value)); checkLengthLimit(); } diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/AnyNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/AnyNodes.java index ae2d74f23..e358f5e01 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/AnyNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/AnyNodes.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,10 +38,16 @@ public final class AnyNodes { } public abstract static class toString extends ExternalMethod0Node { + @Specialization + @TruffleBoundary + protected String evalString(VmValue vmValue) { + return vmValue.toPklString(); + } + @Specialization @TruffleBoundary protected String evalString(Object self) { - return self.toString(); + return VmUtils.toPklString(self); } } @@ -50,7 +56,7 @@ public final class AnyNodes { @Specialization @SuppressWarnings("UnusedParameters") - protected VmNull eval(VmNull self, VmFunction function) { + protected VmNull eval(VmNull self, VmFunction ignored) { return self; } diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/JsonRendererNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/JsonRendererNodes.java index 5faf4b39c..4f4ac7284 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/JsonRendererNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/JsonRendererNodes.java @@ -93,7 +93,9 @@ public final class JsonRendererNodes { @Override public void visitFloat(Double value) { if (value.isNaN() || value.isInfinite()) { - throw new VmExceptionBuilder().evalError("cannotRenderValue", value, name).build(); + throw new VmExceptionBuilder() + .evalError("cannotRenderValue", VmUtils.toPklString(value), name) + .build(); } builder.append((double) value); } diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java index cb40d397c..74fc80b34 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java @@ -292,7 +292,8 @@ public final class ListingNodes { if (!key.equals(0L)) { builder.append(separator); } - builder.append(value); + // TODO: use ToStringNode + builder.append(VmUtils.toPklString(value)); return true; }); LoopNode.reportLoopCount(this, self.getLength()); diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/PcfRenderer.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/PcfRenderer.java index bdfa72140..1a1087136 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/PcfRenderer.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/PcfRenderer.java @@ -92,17 +92,17 @@ public final class PcfRenderer extends AbstractStringRenderer { @Override public void visitDuration(VmDuration value) { - builder.append(value); + builder.append(value.toPklString()); } @Override public void visitDataSize(VmDataSize value) { - builder.append(value); + builder.append(value.toPklString()); } @Override public void visitBytes(VmBytes value) { - builder.append(value); + builder.append(value.toPklString()); } @Override @@ -116,12 +116,12 @@ public final class PcfRenderer extends AbstractStringRenderer { @Override public void visitRegex(VmRegex value) { - builder.append(value); + builder.append(value.toPklString()); } @Override public void visitIntSeq(VmIntSeq value) { - builder.append(value); + builder.append(value.toPklString()); } @Override diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/PropertiesRendererNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/PropertiesRendererNodes.java index c74cf5f60..c85e90e06 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/PropertiesRendererNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/PropertiesRendererNodes.java @@ -307,7 +307,7 @@ public final class PropertiesRendererNodes { } else { builder.append( PropertiesUtils.renderPropertiesKeyOrValue( - path.toString(), true, restrictCharset)); + VmUtils.toPklString(path), true, restrictCharset)); } isFollowing.set(true); }); diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java index 5b42525b3..1f3f3894c 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java @@ -534,31 +534,31 @@ public final class RendererNodes { @Override public void visitIntSeq(VmIntSeq value) { writePropertyName(); - builder.append(value); + builder.append(value.toPklString()); } @Override public void visitPair(VmPair value) { writePropertyName(); - builder.append(value); + builder.append(value.toPklString()); } @Override public void visitRegex(VmRegex value) { writePropertyName(); - builder.append(value); + builder.append(value.toPklString()); } @Override public void visitNull(VmNull value) { writePropertyName(); - builder.append(value); + builder.append(value.toPklString()); } @Override public void visitReference(VmReference value) { writePropertyName(); - builder.append(value); + builder.append(value.toPklString()); } /** diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl index 05db31add..ce7f9df47 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl @@ -508,4 +508,9 @@ examples { List(1, "Pigeon", 3.d).reverse() List().reverse() } + + ["join()"] { + List(1.s, 2.s).join(", ") + List(1.mb, 2.gb).join(", ") + } } diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/propertiesRenderer13.properties.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/propertiesRenderer13.properties.pkl new file mode 100644 index 000000000..77fed09d4 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/propertiesRenderer13.properties.pkl @@ -0,0 +1,4 @@ +output { + value = Map(5.s, "value") + renderer = new PropertiesRenderer {} +} diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl index a47e6c5d8..36b603d17 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl @@ -440,4 +440,9 @@ examples { Set(1, "Pigeon", 3.d).reverse() Set().reverse() } + + ["join()"] { + Set(1.s, 2.s).join(", ") + Set(1.mb, 2.gb).join(", ") + } } diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/stackTraceWithDataSizeEntryName.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/stackTraceWithDataSizeEntryName.pkl new file mode 100644 index 000000000..5215a98c3 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/stackTraceWithDataSizeEntryName.pkl @@ -0,0 +1,3 @@ +one { + [5.mb] = throw("ouch") +} diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/stackTraceWithDurationEntryName.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/stackTraceWithDurationEntryName.pkl new file mode 100644 index 000000000..5d13c6957 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/stackTraceWithDurationEntryName.pkl @@ -0,0 +1,3 @@ +one { + [5.s] = throw("ouch") +} diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf index dc432e415..1e28f74ae 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf @@ -438,4 +438,8 @@ examples { List(3.d, "Pigeon", 1) List() } + ["join()"] { + "1.s, 2.s" + "1.mb, 2.gb" + } } diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/propertiesRenderer13.properties b/pkl-core/src/test/files/LanguageSnippetTests/output/api/propertiesRenderer13.properties new file mode 100644 index 000000000..1e2cf2b3a --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/propertiesRenderer13.properties @@ -0,0 +1 @@ +5.s = value diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf index edf73b1ac..d66e6c095 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf @@ -377,4 +377,8 @@ examples { List(3.d, "Pigeon", 1) List() } + ["join()"] { + "1.s, 2.s" + "1.mb, 2.gb" + } } diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/stackTraceWithDataSizeEntryName.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/stackTraceWithDataSizeEntryName.err new file mode 100644 index 000000000..fe09c1bab --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/stackTraceWithDataSizeEntryName.err @@ -0,0 +1,14 @@ +–– Pkl Error –– +ouch + +x | [5.mb] = throw("ouch") + ^^^^^^^^^^^^^ +at stackTraceWithDataSizeEntryName#one[5.mb] (file:///$snippetsDir/input/errors/stackTraceWithDataSizeEntryName.pkl) + +xxx | renderer.renderDocument(value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at pkl.base#Module.output.text (pkl:base) + +xxx | if (renderer is BytesRenderer) renderer.renderDocument(value) else text.encodeToBytes("UTF-8") + ^^^^ +at pkl.base#Module.output.bytes (pkl:base) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/stackTraceWithDurationEntryName.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/stackTraceWithDurationEntryName.err new file mode 100644 index 000000000..d8bb3d50f --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/stackTraceWithDurationEntryName.err @@ -0,0 +1,14 @@ +–– Pkl Error –– +ouch + +x | [5.s] = throw("ouch") + ^^^^^^^^^^^^^ +at stackTraceWithDurationEntryName#one[5.s] (file:///$snippetsDir/input/errors/stackTraceWithDurationEntryName.pkl) + +xxx | renderer.renderDocument(value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at pkl.base#Module.output.text (pkl:base) + +xxx | if (renderer is BytesRenderer) renderer.renderDocument(value) else text.encodeToBytes("UTF-8") + ^^^^ +at pkl.base#Module.output.bytes (pkl:base) diff --git a/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt b/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt index 783dbc975..6190f3da3 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt @@ -94,6 +94,13 @@ class EvaluatorTest { checkModule(module) } + @Test + fun `evaluate text with dynamic entry keyed by a non-identifier value`() { + val module = evaluator.evaluate(text("""result = new Dynamic { [5.s] = "value" }""")) + val result = module.getProperty("result") as PObject + assertThat(result.properties).containsEntry("5.s", "value") + } + @Test fun `evaluate text with relative import`() { val e = assertThrows { evaluator.evaluate(text("import \"foo.bar\"")) } diff --git a/pkl-core/src/test/kotlin/org/pkl/core/util/ErrorMessagesTest.kt b/pkl-core/src/test/kotlin/org/pkl/core/util/ErrorMessagesTest.kt index 14fe1cee0..3ec2b811c 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/util/ErrorMessagesTest.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/util/ErrorMessagesTest.kt @@ -42,7 +42,7 @@ class ErrorMessagesTest { override fun equals(obj: Any?): Boolean = this === obj - override fun toString(): String { + override fun toPklString(): String { force(true) return "lazy" }