Improve error message thrown for "cannot instantiate" (#1916)
If the parent comes from an implicit node (e.g. read super entry node), Pkl will currently bury its source section when rendering the error message.
This commit is contained in:
1 parent
ce977f1ffe
commit
a06684b2c0
9 files changed
+48
-13
No files matched your search
+5
-3
@@ -98,7 +98,7 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
|
||||
@Specialization(guards = "checkObjectCannotHaveParameters()")
|
||||
protected VmTyped evalTyped(VirtualFrame frame, VmTyped parent) {
|
||||
VmUtils.checkIsInstantiable(parent.getVmClass(), getParentNode());
|
||||
VmUtils.checkIsInstantiable(parent.getVmClass(), getParentNode(), this);
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return parent;
|
||||
@@ -207,7 +207,7 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
|
||||
@Specialization(guards = {"isTypedObjectClass(parent)", "checkObjectCannotHaveParameters()"})
|
||||
protected VmTyped evalTypedObjectClass(VirtualFrame frame, VmClass parent) {
|
||||
VmUtils.checkIsInstantiable(parent, getParentNode());
|
||||
VmUtils.checkIsInstantiable(parent, getParentNode(), this);
|
||||
var data = executeChildren(frame, parent, 0);
|
||||
if (data.hasNoMembers()) {
|
||||
return parent.getPrototype();
|
||||
@@ -225,7 +225,9 @@ public abstract class GeneratorObjectLiteralNode extends ObjectLiteralNode {
|
||||
value = getNullDefaultValue(vmNull);
|
||||
}
|
||||
VmUtils.checkIsInstantiable(
|
||||
value instanceof VmClass vmClass ? vmClass : VmUtils.getClass(value), getParentNode());
|
||||
value instanceof VmClass vmClass ? vmClass : VmUtils.getClass(value),
|
||||
getParentNode(),
|
||||
this);
|
||||
|
||||
throw exceptionBuilder().unreachableCode().build();
|
||||
}
|
||||
|
||||
+2
-2
@@ -52,7 +52,7 @@ public abstract class EmptyObjectLiteralNode extends ExpressionNode {
|
||||
return VmDynamic.empty();
|
||||
}
|
||||
|
||||
VmUtils.checkIsInstantiable(parent, getParentNode());
|
||||
VmUtils.checkIsInstantiable(parent, getParentNode(), this);
|
||||
return parent.getPrototype();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public abstract class EmptyObjectLiteralNode extends ExpressionNode {
|
||||
@TruffleBoundary
|
||||
protected void fallback(Object parent) {
|
||||
assert !(parent instanceof VmClass);
|
||||
VmUtils.checkIsInstantiable(VmUtils.getClass(parent), getParentNode());
|
||||
VmUtils.checkIsInstantiable(VmUtils.getClass(parent), getParentNode(), this);
|
||||
throw exceptionBuilder().unreachableCode().build();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -72,7 +72,7 @@ public abstract class SpecializedObjectLiteralNode extends ObjectLiteralNode {
|
||||
@Idempotent
|
||||
protected boolean checkIsValidTypedAmendment(Object parent) {
|
||||
var parentClass = parent instanceof VmClass vmClass ? vmClass : VmUtils.getClass(parent);
|
||||
VmUtils.checkIsInstantiable(parentClass, getParentNode());
|
||||
VmUtils.checkIsInstantiable(parentClass, getParentNode(), this);
|
||||
|
||||
for (var member : EconomicMaps.getValues(members)) {
|
||||
if (member.isLocal()) continue;
|
||||
@@ -290,7 +290,7 @@ public abstract class SpecializedObjectLiteralNode extends ObjectLiteralNode {
|
||||
Object parent, @Nullable ObjectMember firstElemOrEntry, boolean isElementsOnly) {
|
||||
var parentIsClass = parent instanceof VmClass;
|
||||
var parentClass = parentIsClass ? (VmClass) parent : VmUtils.getClass(parent);
|
||||
VmUtils.checkIsInstantiable(parentClass, getParentNode());
|
||||
VmUtils.checkIsInstantiable(parentClass, getParentNode(), this);
|
||||
|
||||
var property = findFirstNonDefaultProperty(members);
|
||||
if (property != null
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public abstract class AbstractInferParentNode extends ExpressionNode {
|
||||
// try to produce a more specific error message than "cannotInstantiateType"
|
||||
var clazz = typeNode.getType().getVmClass();
|
||||
if (clazz != null) {
|
||||
VmUtils.checkIsInstantiable(clazz, typeNode);
|
||||
VmUtils.checkIsInstantiable(clazz, typeNode, this);
|
||||
}
|
||||
|
||||
throw exceptionBuilder()
|
||||
|
||||
@@ -903,7 +903,7 @@ public final class VmUtils {
|
||||
return resolvedNodes;
|
||||
}
|
||||
|
||||
public static void checkIsInstantiable(VmClass parentClass, @Nullable Node parentNode) {
|
||||
public static void checkIsInstantiable(VmClass parentClass, Node parentNode, Node callerNode) {
|
||||
if (parentClass.isInstantiable()) return;
|
||||
|
||||
CompilerDirectives.transferToInterpreter();
|
||||
@@ -911,14 +911,15 @@ public final class VmUtils {
|
||||
if (parentClass.isAbstract()) {
|
||||
throw new VmExceptionBuilder()
|
||||
.evalError("cannotInstantiateAbstractClass", parentClass)
|
||||
.withOptionalLocation(parentNode)
|
||||
.withOptionalLocation(
|
||||
parentNode.getSourceSection().isAvailable() ? parentNode : callerNode)
|
||||
.build();
|
||||
}
|
||||
|
||||
assert parentClass.isExternal();
|
||||
throw new VmExceptionBuilder()
|
||||
.evalError("cannotInstantiateExternalClass", parentClass)
|
||||
.withOptionalLocation(parentNode)
|
||||
.withOptionalLocation(parentNode.getSourceSection().isAvailable() ? parentNode : callerNode)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public final class DynamicNodes {
|
||||
throw exceptionBuilder().evalError("notASubclassOfTyped", clazz).build();
|
||||
}
|
||||
|
||||
VmUtils.checkIsInstantiable(clazz, this);
|
||||
VmUtils.checkIsInstantiable(clazz, this, this);
|
||||
|
||||
var result =
|
||||
new VmTyped(
|
||||
|
||||
@@ -255,7 +255,7 @@ public final class MapNodes {
|
||||
throw exceptionBuilder().evalError("notASubclassOfTyped", clazz).build();
|
||||
}
|
||||
|
||||
VmUtils.checkIsInstantiable(clazz, null);
|
||||
VmUtils.checkIsInstantiable(clazz, this, this);
|
||||
|
||||
var result =
|
||||
new VmTyped(
|
||||
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
class Holder {
|
||||
name: String
|
||||
}
|
||||
|
||||
base: Holder = new {
|
||||
name = "base"
|
||||
}
|
||||
|
||||
result: Holder = (base) {
|
||||
name {
|
||||
"foo"
|
||||
}
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
–– Pkl Error ––
|
||||
Cannot instantiate, or amend an instance of, external class `String`.
|
||||
|
||||
xx | name {
|
||||
^^^^^^
|
||||
at cannotInstantiateExternalClass#result.name (file:///$snippetsDir/input/errors/cannotInstantiateExternalClass.pkl)
|
||||
|
||||
To create an instance of an external class, use its literal syntax or constructor method.
|
||||
Examples:
|
||||
* `123` uses literal syntax to create an instance of class `Int`.
|
||||
* `Pair(1, 2)` uses the `Pair()` constructor method to create an instance of class `Pair`.
|
||||
|
||||
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)
|
||||
Reference in new issue
Block a user