Fixes Temporal Duration total edge case and GC collection#10
Conversation
|
No actionable comments were generated in the recent review. 🎉 📝 WalkthroughWalkthroughAdds tests and runtime guards for Temporal.Duration.total to forbid totals when years/months are present without relativeTo, and changes Temporal initialization and PlainDate subtraction to use temporary GC roots for safer lifetime management. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Benchmark Results113 benchmarks · 113 unchanged · avg +0.1% arrays.js — 11 unchanged · avg -0.2%
classes.js — 10 unchanged · avg +0.5%
closures.js — 11 unchanged · avg -0.2%
collections.js — 12 unchanged · avg +0.2%
destructuring.js — 14 unchanged · avg -0.8%
fibonacci.js — 3 unchanged · avg +0.7%
json.js — 11 unchanged · avg +1.5%
numbers.js — 11 unchanged · avg -0.4%
objects.js — 7 unchanged · avg +0.0%
promises.js — 12 unchanged · avg -0.1%
strings.js — 11 unchanged · avg +0.0%
Measured on ubuntu-latest x64. Changes within ±7% are considered insignificant. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
units/Goccia.Values.TemporalDuration.pas (1)
513-529:⚠️ Potential issue | 🟠 MajorExtract and validate
relativeTobefore checking year/month duration intotal()The guard at lines 528–529 throws "requires relativeTo" but the preceding code never reads
relativeTofrom the options object. Calls likeduration.total({ unit: "days", relativeTo })will incorrectly throw the error even thoughrelativeTowas provided. Additionally, the subsequent calculation ignores years/months without relativeTo support (which is scientifically invalid—month-to-day conversion requires date context).Extract
relativeTofrom the options object and either implement year/month calculation with it, or throw a clearer "not supported yet" error before the computation.Suggested approach
else if Arg is TGocciaObjectValue then begin + OptsObj := TGocciaObjectValue(Arg); - Arg := TGocciaObjectValue(Arg).GetProperty('unit'); + Arg := OptsObj.GetProperty('unit'); if (Arg = nil) or (Arg is TGocciaUndefinedLiteralValue) then ThrowRangeError('total() requires a unit option'); UnitStr := Arg.ToStringLiteral.Value; + Arg := OptsObj.GetProperty('relativeTo'); + HasRelativeTo := Assigned(Arg) and not (Arg is TGocciaUndefinedLiteralValue); end - if (D.FYears <> 0) or (D.FMonths <> 0) then - ThrowRangeError('Duration with years or months requires relativeTo for total()'); + if (D.FYears <> 0) or (D.FMonths <> 0) then + begin + if not HasRelativeTo then + ThrowRangeError('Duration with years or months requires relativeTo for total()') + else + ThrowRangeError('Duration.total with relativeTo is not supported yet'); + end;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@units/Goccia.Values.TemporalDuration.pas` around lines 513 - 529, The total() implementation reads the 'unit' from Arg when Arg is a TGocciaObjectValue but never extracts or validates a 'relativeTo' property before rejecting durations with years/months; update the TGocciaObjectValue branch to also call GetProperty('relativeTo') (e.g. store to a local like RelToArg), treat nil or TGocciaUndefinedLiteralValue as “no relativeTo provided”, and only ThrowRangeError('Duration with years or months requires relativeTo for total()') if D.FYears or D.FMonths are non‑zero and RelToArg is absent; if RelToArg is present, pass it into the subsequent year/month conversion path or throw a clearer “not supported yet” error before attempting conversion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@units/Goccia.Values.TemporalDuration.pas`:
- Around line 513-529: The total() implementation reads the 'unit' from Arg when
Arg is a TGocciaObjectValue but never extracts or validates a 'relativeTo'
property before rejecting durations with years/months; update the
TGocciaObjectValue branch to also call GetProperty('relativeTo') (e.g. store to
a local like RelToArg), treat nil or TGocciaUndefinedLiteralValue as “no
relativeTo provided”, and only ThrowRangeError('Duration with years or months
requires relativeTo for total()') if D.FYears or D.FMonths are non‑zero and
RelToArg is absent; if RelToArg is present, pass it into the subsequent
year/month conversion path or throw a clearer “not supported yet” error before
attempting conversion.
- Line comment loop now uses IsLineTerminator (matching SkipComment) instead of checking only #10/#13, so LS (U+2028) and PS (U+2029) correctly terminate single-line comments inside ${...} expressions - Add ES2026 §12.9.4 spec reference to ScanInterpolationExpression Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Handle template interpolation boundaries lexically
- Teach the lexer to track strings, comments, and nested templates inside `${...}`
- Split template segments on lexer boundary markers instead of brace counting
* Address review feedback: fix column tracking, remove Trim, add LS/PS
- Fix CR line terminator column tracking in ScanInterpolationExpression
and ScanNestedTemplateInExpression to use FColumn := 1 (matching
SkipWhitespace/SkipBlockComment/ConsumeUnicodeLineTerminator pattern)
- Add LS (U+2028) and PS (U+2029) line terminator handling in both
new methods for consistency with ScanTemplate
- Remove Trim() from expression text extraction — trailing newlines
are semantically required to terminate // line comments inside
interpolation expressions
- Add regression test for line comment at end of interpolation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Use IsLineTerminator for line comments in interpolation scanner
- Line comment loop now uses IsLineTerminator (matching SkipComment)
instead of checking only #10/#13, so LS (U+2028) and PS (U+2029)
correctly terminate single-line comments inside ${...} expressions
- Add ES2026 §12.9.4 spec reference to ScanInterpolationExpression
… tests ES2019 (proposal-json-superset) allows U+2028 and U+2029 in string literals. Only LF and CR remain forbidden. Corrects the lexer check from IsLineTerminator (which includes LS/PS) to Peek = #10 or #13. Moves tests from Pascal unit layer to CLI CI layer (scripts/test-cli-lexer.ts) — the correct home for lexer error verification. Adds positive LS/PS test to string-literals.js. Restores raw LS/PS bytes in RegExp/unicode.js that were incorrectly escaped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Reject unescaped line terminators in string literals per ES2026 §12.9.4 The lexer now raises SyntaxError when a raw LF, CR, LS (U+2028), or PS (U+2029) appears inside a single- or double-quoted string literal. LineContinuation (backslash before line terminator) remains valid. Also fixes TGocciaLexerError not being recognized as SyntaxError by try/catch in user code and the toThrow() test matcher. Closes #619 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Replace Function-constructor JS tests with Pascal lexer tests Remove the JS test directory that used new Function() and add proper Pascal unit tests to Goccia.Lexer.Test.pas instead — covers all four line terminators (LF, CR, LS, PS) and verifies LineContinuation still produces the expected value. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix: only reject LF/CR in strings, allow LS/PS per ES2019; use CLI CI tests ES2019 (proposal-json-superset) allows U+2028 and U+2029 in string literals. Only LF and CR remain forbidden. Corrects the lexer check from IsLineTerminator (which includes LS/PS) to Peek = #10 or #13. Moves tests from Pascal unit layer to CLI CI layer (scripts/test-cli-lexer.ts) — the correct home for lexer error verification. Adds positive LS/PS test to string-literals.js. Restores raw LS/PS bytes in RegExp/unicode.js that were incorrectly escaped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Update suggestion to mention both \n and \r escapes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add single-quoted CRLF rejection test case
Summary by CodeRabbit