fix: make jcpan -t DateTimeX::Easy pass (regex + warnings + Time::HiRes/Piece fixes)#560
Merged
fix: make jcpan -t DateTimeX::Easy pass (regex + warnings + Time::HiRes/Piece fixes)#560
Conversation
`sleep` was missing from the OVERRIDABLE_OP list, so user code installing
`*CORE::GLOBAL::sleep = sub { ... }` was silently bypassed and the native
`sleep` ran instead. Adding it lets Test::MockTime::HiRes (and any other
time-mocking module) intercept `sleep` to advance a mocked clock without
actually waiting.
Also adds a new `sleep operator override` subtest in operator_overrides.t
covering this code path, and adds dev/modules/jcpan_datetimex_easy.md
tracking the broader DateTimeX::Easy install plan.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
`BEGIN { unimport warnings qw(Cat) }` inside a sub body sets
WarningFlags.lastScopeId at compile time, but parseSpecialBlock returned a
plain `undef` node and never emitted a CompilerFlagNode. The result was that
the surrounding lexical scope did not get `local ${^WARNING_SCOPE} = N`
emitted at runtime, so warnings::warnif() did not honor the suppression.
Mirror the tail of parseUseDeclaration: after a BEGIN block runs, capture
the current symbol-table flags + lastScopeId into a CompilerFlagNode so the
runtime sees the change. This is the idiom Module::Util uses to silence
File::Find's "Can't stat" warning when given a non-existent search path,
and it unblocks Module::Util's t/01..module.t test 44.
Adds a unit test in src/test/resources/unit/warnings.t covering the
File::Find use case.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two related preprocessor bugs that together blocked Date::Manip and any
CPAN module that uses Perl 5.10+ duplicate-name capture groups:
1. `(?<x>a)|(?<x>b)` is legal Perl but Java rejects "Named capturing
group <x> is already defined". Now RegexPreprocessor tracks names it
has emitted and suffixes the second-and-later occurrences with a
distinctive marker (`ZpjdupZ<N>`); CaptureNameEncoder.decodeGroupName
strips the marker so user code sees the original name in `%+`/`%-`.
HashSpecialVariable groups the duplicates back together so
`$+{name}` returns the matched alternative and `$-{name}` returns
an arrayref of all alternatives (matching Perl's semantics).
2. With /i, `expandMultiCharFolds` was rewriting characters inside
`(?<name>...)` group names — e.g. `(?<off>...)/i` was turning into
`(?<o(?:ff|fi)>...)`, which Java rejects. Group names are syntactic
identifiers, not pattern text, so the preprocessor now skips over
the name portion of named captures (`(?<name>`, `(?'name'`,
`(?P<name>`, `(?P=name)`) before applying fold expansion.
Together these unblock Date::Manip-based modules
(DateTime::Format::DateManip, DateTime::Format::Natural via Date::Manip,
etc.) and many other CPAN modules that rely on the duplicate-name idiom.
Adds 6 subtests to regex/regex_named_capture.t covering both fixes.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Issues A (duplicate named captures), C (silent missing-path / warning-scope after BEGIN), and D (CORE::GLOBAL::sleep) are done. Issue B (DateTime::Format::Natural parse_success failures) remains as planned follow-up. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
`s/\G.../.../` was scanning from offset 0 even when pos() was set by a
previous /g match. As a result, an idiom like
$s =~ /pattern/g; # leaves pos($s) at end of match
$s =~ s/\G/:00/; # should insert at pos(), not at 0
prepended the replacement to the start of the string instead of
appending at the previous match end. DateTime::Format::Natural relies
on this idiom to rewrite "feb 28 at 3" into "feb 28 at 3:00" before
parsing.
replaceRegex() now mirrors matchRegex(): when the pattern uses \G it
looks up RuntimePosLvalue.pos(string) and, if defined, sets the
matcher's region to start there (with useAnchoringBounds(false) so
^/$ in /m don't anchor at the artificial boundary).
Adds a unit test in regex/regex_g_pos.t.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two small fixes that together let DateTime::Format::Natural's
mock-time tests run, which was the last missing piece for
`jcpan -t DateTimeX::Easy` to pass end-to-end.
* `Time::HiRes::gettimeofday` in scalar/void context returned just the
microseconds component (e.g. `924972`) instead of the floating-point
epoch (`1777146550.92...`). It now mirrors real Perl: scalar context
yields `seconds + micros / 1_000_000`, list context still yields the
`(seconds, microseconds)` integer pair.
* `Time::Piece->strptime` was rejecting non-padded numeric fields
("1:13:8" against "%H:%M:%S") because Java's `HH`/`mm`/`ss` require
exactly two digits. Switched the formatter to a lenient builder
(`DateTimeFormatterBuilder.parseLenient().appendPattern(...)`) so
POSIX-style "1:13:8" now parses, matching real Perl.
`jcpan -t DateTimeX::Easy` now exits 0:
DateTime::Format::DateManip 7 tests PASS
DateTime::Set 959 tests PASS
Module::Util 47 tests PASS
Test::MockTime::HiRes 216 tests PASS
DateTime::Format::Natural 11077 tests PASS
DateTimeX::Easy 107 tests PASS
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
`jcpan -t DateTimeX::Easy` now passes (107/107). Updated the progress section with all six commits and the final test counts. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Six fixes that together make
jcpan -t DateTimeX::Easyexit 0 (was completelyblocked on a regex compilation error). Plan and progress tracked in
dev/modules/jcpan_datetimex_easy.md.CORE::GLOBAL::sleepoverridesleepwas missing fromOVERRIDABLE_OP;Test::MockTime::HiRescouldn't interceptsleepBEGIN { unimport warnings ... }parseSpecialBlocknow emits aCompilerFlagNodeafter BEGIN solocal ${^WARNING_SCOPE} = Npropagates to runtime — needed byModule::Utiland any module that usesBEGIN { unimport warnings 'cat' }inside a sub/iname protection(?<x>a)|(?<x>b)is legal Perl but Java rejects duplicates; preprocessor now suffixes second-and-later occurrences withZpjdupZ<N>andHashSpecialVariablegroups them back together for%+/%-. Also stops/imulti-char fold expansion from corrupting capture-group names ((?<off>...)/iwas becoming(?<o(?:ff|fi)>...))s/\G.../.../honorspos()\Gand the previous/gmatch leftpos()set;DateTime::Format::Natural::Rewriterelies on this idiomTime::HiRes::gettimeofdayin scalar contextseconds + micros/1_000_000Time::Piece->strptimelenient parsingEffect on
jcpan -t DateTimeX::Easyjcpan -t DateTimeX::Easynow exits 0.Test plan
makegreen (all parallel unit shards pass)src/test/resources/unit/operator_overrides.t—sleepoverridesrc/test/resources/unit/warnings.t— BEGIN-unimport-warnings inside subsrc/test/resources/unit/regex/regex_named_capture.t— duplicate names +/iname foldsrc/test/resources/unit/regex/regex_g_pos.t—\Gins///honorspos()jcpan -t DateTimeX::Easyexits 0 from a clean build directoryGenerated with Devin