fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92) - #93

Merged
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast
Aug 29, 2026
Merged

fix: getValue/inDayTimeRange/toNum — 3 glm-hunt bugs (#90 #91 #92)#93
opaopa6969 merged 1 commit into
masterfrom
fix/issue-90-getvalue-cast

Conversation

@opaopa6969

Copy link
Copy Markdown
Owner

Summary

Fixes three [glm-hunt] issues reported in the previous stage. Each is a small, independent, reversible bug fix; bundled into one PR because the touch points do not overlap and splitting would only add CI/merge overhead.

Closes#90
Closes#91
Closes#92

Why one PR

The three bugs live in two files (AbstractCalculationContext.java, P4TypedAstEvaluator.java) and do not interact. Each fix is minimal and locally reversible (revert the relevant hunk only). Bundling avoids three CI runs and three merge commits for what is effectively a single bug-hunt pass.

Changes

#90getValue() ClassCastException on non-Float Number

AbstractCalculationContext.getValue(String) did (Float) valueByName.get(name), but set(String, Number) stores arbitrary Number subtypes (Double/Integer/BigInteger...). Reading such a value via getValue threw ClassCastException, affecting e.g. inTimeRange/getValue("nowHour") after a set(String, Number) declaration.

Fix: read as Number; if not already Float, convert via number.floatValue(). Float values are preserved exactly (no extra boxing). Empty map → Optional.empty() as before.

#91toNum() ClassCastException + missing castToNumberType

P4TypedAstEvaluator.evalToNumExpr returned a raw Double (ignoring the configured numberType) and cast the default value via (Number) eval(...), so a non-Number default (toNum('abc','xyz'), toNum('abc', true)) threw ClassCastException. Other number functions (sin/sqrt/abs...) already route through castToNumberType; only toNum was inconsistent. The JavaCode backend rejects non-Number defaults at parse time, so this also improves cross-backend parity (AST no longer crashes at eval time).

Fix: route both the parsed value and the default through castToNumberType(double); when the default is not a Number, fall back to 0.0 instead of throwing. This is the minimal safe option; tightening the grammar to reject non-Number defaults at parse time is a larger change left for a follow-up if desired.

#92inDayTimeRange always false for same-day midnight span

inDayTimeRange(MONDAY, 22, MONDAY, 6) (same day, fromHour > toHour) always returned false, while EmbeddedFunction.inTimeRange(22, 6) treats fromHour > toHour as a midnight span and returns true for 23/3. User intent ("Monday 22:00 → Tuesday 06:00" expressed intra-day) was silently dropped.

Fix: when the from/to days are equal and fromHour > toHour, evaluate as a midnight span (nowHour >= fromHour || nowHour < toHour), mirroring inTimeRange. Normal same-day ranges are unchanged.

Tests

  • Issue90GetValueCastTestset(String, Number) with Double/Integer/BigInteger; getValue returns the floatValue(); Float path exact; absent → empty.
  • Issue91ToNumTest — non-Number defaults no longer throw; toNum('3.14', 0) returns Float for numberType=_float and Double for numberType=_double; default value is cast through numberType.
  • Issue92InDayTimeRangeTest — same-day midnight span includes 23/3/22, excludes 6 (boundary) and 12 (gap); consistency with inTimeRange; normal same-day range still works.

Full suite: 703 tests, 0 failures (9 pre-existing skips).

Risk / revert

All changes are additive/safe-conversion paths; no public API signature changes. Revert is git revert <commit> (single commit) or per-hunk.

…nsistent, toNum() cast through numberType
Fix three glm-hunt bugs in CalculationContext / P4TypedAstEvaluator:
#90: AbstractCalculationContext.getValue() did an unchecked (Float) cast on
valueByName, so set(String, Number) with Double/Integer/BigInteger etc.
caused ClassCastException on read. Convert via Number.floatValue() when
the stored value is not already a Float; Float values are preserved as-is.
#91: P4TypedAstEvaluator.evalToNumExpr() returned a raw Double and cast the
default value via (Number), causing ClassCastException for non-Number
defaults (e.g. toNum('abc','xyz')) and ignoring the configured numberType.
Route both the parsed value and the default through castToNumberType so
the result honors numberType, and fall back to 0.0 when the default is
not a Number instead of throwing.
#92: AbstractCalculationContext.inDayTimeRange() returned false for a
same-day range with fromHour > toHour (a midnight-spanning range),
inconsistent with EmbeddedFunction.inTimeRange(). When fromHour >
toHour on the same day, evaluate as a midnight span
(nowHour >= fromHour || nowHour < toHour), matching inTimeRange().
Each bug is covered by a dedicated regression test (Issue90/91/92*Test).
Full test suite passes (703 tests, 0 failures).
@opaopa6969
opaopa6969 merged commit 5ae6675 into masterAug 29, 2026
1 check passed
@opaopa6969
opaopa6969 deleted the fix/issue-90-getvalue-cast branch August 29, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment