From 2f0436ff2f2cf554ae2624d8b4b1dae9946c6967 Mon Sep 17 00:00:00 2001 From: luuvish Date: Wed, 17 Apr 2024 06:45:33 +0900 Subject: [PATCH] Cannot assign property with fixed/const in spread (#428) When using spread syntax with typed object, properties that are fixed or const cannot be assigned or amended. This should be checked in the checkTypedProperty() function. --- .../generator/GeneratorSpreadNode.java | 46 +++++++++++++------ .../errors/cannotAssignFixedProperty3.pkl | 5 ++ .../errors/cannotAssignFixedProperty3.err | 14 ++++++ 3 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/cannotAssignFixedProperty3.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/cannotAssignFixedProperty3.err 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)