diff --git a/pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorSpreadNode.java b/pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorSpreadNode.java index bd102c22..4fda8573 100644 --- a/pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorSpreadNode.java +++ b/pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorSpreadNode.java @@ -343,19 +343,39 @@ public abstract class GeneratorSpreadNode extends GeneratorMemberNode { } protected void checkTypedProperty(VmClass clazz, ObjectMember member) { - if (member.isLocal() || clazz.hasProperty(member.getName())) return; - CompilerDirectives.transferToInterpreter(); - var exception = - exceptionBuilder() - .cannotFindProperty(clazz.getPrototype(), member.getName(), false, false) - .build(); - if (member.getHeaderSection().isAvailable()) { - exception - .getInsertedStackFrames() - .put( - getRootNode().getCallTarget(), - VmUtils.createStackFrame(member.getHeaderSection(), member.getQualifiedName())); + if (member.isLocal()) return; + + var memberName = member.getName(); + if (!clazz.hasProperty(memberName)) { + CompilerDirectives.transferToInterpreter(); + var exception = + exceptionBuilder() + .cannotFindProperty(clazz.getPrototype(), memberName, false, false) + .build(); + if (member.getHeaderSection().isAvailable()) { + exception + .getInsertedStackFrames() + .put( + getRootNode().getCallTarget(), + VmUtils.createStackFrame(member.getHeaderSection(), member.getQualifiedName())); + } + throw exception; + } + + var classProperty = clazz.getProperty(memberName); + if (classProperty != null && classProperty.isConstOrFixed()) { + CompilerDirectives.transferToInterpreter(); + var errMsg = + classProperty.isConst() ? "cannotAssignConstProperty" : "cannotAssignFixedProperty"; + var exception = exceptionBuilder().evalError(errMsg, memberName).build(); + if (member.getHeaderSection().isAvailable()) { + exception + .getInsertedStackFrames() + .put( + getRootNode().getCallTarget(), + VmUtils.createStackFrame(member.getHeaderSection(), member.getQualifiedName())); + } + throw exception; } - throw exception; } } diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/cannotAssignFixedProperty3.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/cannotAssignFixedProperty3.pkl new file mode 100644 index 00000000..324062bf --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/cannotAssignFixedProperty3.pkl @@ -0,0 +1,5 @@ +amends "../basic/fixedProperty2.pkl" + +p = new { + ...new Dynamic { name = "Osprey" } +} diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/cannotAssignFixedProperty3.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/cannotAssignFixedProperty3.err new file mode 100644 index 00000000..1c8ce65d --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/cannotAssignFixedProperty3.err @@ -0,0 +1,14 @@ +–– Pkl Error –– +Cannot assign to fixed property `name`. + +x | ...new Dynamic { name = "Osprey" } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at cannotAssignFixedProperty3#p (file:///$snippetsDir/input/errors/cannotAssignFixedProperty3.pkl) + +x | ...new Dynamic { name = "Osprey" } + ^^^^ +at cannotAssignFixedProperty3#p.name (file:///$snippetsDir/input/errors/cannotAssignFixedProperty3.pkl) + +xxx | text = renderer.renderDocument(value) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at pkl.base#Module.output.text (pkl:base)