Improve error message when amending a property with no value set (#1867)
Improve error message when amending a property with no value set This decorates error messages with the amendment node.
This commit is contained in:
1 parent
e0b3b87e19
commit
cbffd6c114
9 files changed
+149
-1
No files matched your search
+27
-1
@@ -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.
|
||||
@@ -15,11 +15,13 @@
|
||||
*/
|
||||
package org.pkl.core.ast.expression.literal;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives;
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.dsl.Fallback;
|
||||
import com.oracle.truffle.api.dsl.ImportStatic;
|
||||
import com.oracle.truffle.api.dsl.NodeChild;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import com.oracle.truffle.api.source.SourceSection;
|
||||
import org.pkl.core.ast.ExpressionNode;
|
||||
import org.pkl.core.runtime.*;
|
||||
@@ -32,6 +34,8 @@ public abstract class EmptyObjectLiteralNode extends ExpressionNode {
|
||||
super(sourceSection);
|
||||
}
|
||||
|
||||
protected abstract Object executeWithParent(VirtualFrame frame, Object parent);
|
||||
|
||||
protected abstract ExpressionNode getParentNode();
|
||||
|
||||
@Specialization
|
||||
@@ -69,4 +73,26 @@ public abstract class EmptyObjectLiteralNode extends ExpressionNode {
|
||||
VmUtils.checkIsInstantiable(VmUtils.getClass(parent), getParentNode());
|
||||
throw exceptionBuilder().unreachableCode().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object executeGeneric(VirtualFrame frame) {
|
||||
Object parent;
|
||||
try {
|
||||
parent = getParentNode().executeGeneric(frame);
|
||||
} catch (VmException e) {
|
||||
CompilerDirectives.transferToInterpreter();
|
||||
// include object amendment in the error message if error found during eval of parent
|
||||
if (e.getSourceSection() != null
|
||||
&& !e.getSourceSection().equals(sourceSection)
|
||||
// don't include if the originating error's source section is within the bounds of our own
|
||||
// source section.
|
||||
&& !(VmUtils.sourceSectionContains(sourceSection, e.getSourceSection()))) {
|
||||
e.getInsertedStackFrames()
|
||||
.putIfAbsent(
|
||||
getRootNode().getCallTarget(), VmUtils.createStackFrame(sourceSection, null));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return executeWithParent(frame, parent);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import org.pkl.core.ast.type.TypeNode;
|
||||
import org.pkl.core.ast.type.UnresolvedTypeNode;
|
||||
import org.pkl.core.runtime.BaseModule;
|
||||
import org.pkl.core.runtime.VmClass;
|
||||
import org.pkl.core.runtime.VmException;
|
||||
import org.pkl.core.runtime.VmFunction;
|
||||
import org.pkl.core.runtime.VmLanguage;
|
||||
import org.pkl.core.runtime.VmNull;
|
||||
@@ -58,6 +59,8 @@ public abstract class ObjectLiteralNode extends ExpressionNode {
|
||||
this.parameterTypes = parameterTypes;
|
||||
}
|
||||
|
||||
protected abstract Object executeWithParent(VirtualFrame frame, Object parent);
|
||||
|
||||
protected abstract ExpressionNode getParentNode();
|
||||
|
||||
protected abstract ObjectLiteralNode copy(ExpressionNode newParentNode);
|
||||
@@ -114,4 +117,27 @@ public abstract class ObjectLiteralNode extends ExpressionNode {
|
||||
LoopNode.reportLoopCount(this, count);
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object executeGeneric(VirtualFrame frame) {
|
||||
Object parent;
|
||||
try {
|
||||
parent = getParentNode().executeGeneric(frame);
|
||||
} catch (VmException e) {
|
||||
CompilerDirectives.transferToInterpreter();
|
||||
// include object amendment in the error message if error found during eval of parent
|
||||
if (e.getSourceSection() != null
|
||||
&& !e.getSourceSection().equals(sourceSection)
|
||||
// don't include if the originating error's source section is within the bounds of our own
|
||||
// source section.
|
||||
&& !(VmUtils.sourceSectionContains(sourceSection, e.getSourceSection()))) {
|
||||
e.getInsertedStackFrames()
|
||||
.putIfAbsent(
|
||||
getRootNode().getCallTarget(),
|
||||
VmUtils.createStackFrame(sourceSection, qualifiedScopeName));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return executeWithParent(frame, parent);
|
||||
}
|
||||
}
|
||||
@@ -1166,4 +1166,12 @@ public final class VmUtils {
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static boolean sourceSectionContains(SourceSection thisSource, SourceSection otherSource) {
|
||||
if (!thisSource.getSource().equals(otherSource.getSource())) {
|
||||
return false;
|
||||
}
|
||||
return thisSource.getCharIndex() <= otherSource.getCharIndex()
|
||||
&& thisSource.getCharEndIndex() >= otherSource.getCharEndIndex();
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Example {
|
||||
aa: Listing<String> | String
|
||||
}
|
||||
|
||||
res: Example = new {
|
||||
aa { "hello" }
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
open class Parent {
|
||||
bb: *String | Int
|
||||
}
|
||||
|
||||
class Example extends Parent {
|
||||
bb {}
|
||||
}
|
||||
|
||||
res: Example = new {}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class Example {
|
||||
aa: Listing<String> | String
|
||||
bb: Listing<String> = aa
|
||||
}
|
||||
|
||||
res: Example = new {
|
||||
bb {}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
–– Pkl Error ––
|
||||
Tried to read property `aa` but its value is undefined.
|
||||
|
||||
x | aa: Listing<String> | String
|
||||
^^
|
||||
at amendPropertyWithNoDefault1#Example.aa (file:///$snippetsDir/input/errors/amendPropertyWithNoDefault1.pkl)
|
||||
|
||||
The above error occurred when rendering path `res.aa` of module `file:///$snippetsDir/input/errors/amendPropertyWithNoDefault1.pkl`.
|
||||
|
||||
x | aa { "hello" }
|
||||
^^^^^^^^^^^^^^
|
||||
at amendPropertyWithNoDefault1#res.aa (file:///$snippetsDir/input/errors/amendPropertyWithNoDefault1.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)
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
–– Pkl Error ––
|
||||
Tried to read property `bb` but its value is undefined.
|
||||
|
||||
x | bb: *String | Int
|
||||
^^
|
||||
at amendPropertyWithNoDefault2#Parent.bb (file:///$snippetsDir/input/errors/amendPropertyWithNoDefault2.pkl)
|
||||
|
||||
The above error occurred when rendering path `res.bb` of module `file:///$snippetsDir/input/errors/amendPropertyWithNoDefault2.pkl`.
|
||||
|
||||
x | bb {}
|
||||
^^^^^
|
||||
at <unknown> (file:///$snippetsDir/input/errors/amendPropertyWithNoDefault2.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)
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
–– Pkl Error ––
|
||||
Tried to read property `aa` but its value is undefined.
|
||||
|
||||
x | aa: Listing<String> | String
|
||||
^^
|
||||
at amendPropertyWithNoDefault3#Example.aa (file:///$snippetsDir/input/errors/amendPropertyWithNoDefault3.pkl)
|
||||
|
||||
The above error occurred when rendering path `res.aa` of module `file:///$snippetsDir/input/errors/amendPropertyWithNoDefault3.pkl`.
|
||||
|
||||
x | bb: Listing<String> = aa
|
||||
^^
|
||||
at amendPropertyWithNoDefault3#Example.bb (file:///$snippetsDir/input/errors/amendPropertyWithNoDefault3.pkl)
|
||||
|
||||
x | bb {}
|
||||
^^^^^
|
||||
at <unknown> (file:///$snippetsDir/input/errors/amendPropertyWithNoDefault3.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)
|
||||
Reference in new issue
Block a user