Skip to content

refactor: architectural improvements for grouped expressions (demo for PR #863)#876

Draft
rosomri wants to merge 14 commits intoharttle:masterfrom
rosomri:inner_expression_parentheses
Draft

refactor: architectural improvements for grouped expressions (demo for PR #863)#876
rosomri wants to merge 14 commits intoharttle:masterfrom
rosomri:inner_expression_parentheses

Conversation

@rosomri
Copy link
Copy Markdown
Contributor

@rosomri rosomri commented Apr 13, 2026

Summary

This is a demonstration PR showing proposed architectural improvements for PR #863 in response to review comments 4, 6, 8, 9.

Changes

Architectural refactoring (comments 4, 8, 9):

  • Replace resolvedValue: Value with resolvedFilters: Filter[] in GroupedExpressionToken
  • Move evaluation from parse-time to render-time following generator pattern
  • Rename resolveGroupedExpressions() to resolveGroupedExpressionFilters()
  • Evaluate expressions and apply filters lazily via generators in evalGroupedExpressionToken()
  • Maintains proper layering: tokens → render → templates

Code organization (comment 7):

  • Extract extractGroupedExpressionTokenVariables() helper function

Type safety (comment 5):

  • Add explicit ValueToken | GroupedExpressionToken union types for for/tablerow collection properties

Bug fix:

  • Add grouped expression support for tablerow tag (was missing)

Code quality:

  • Remove duplicate getFilter() method in Value class
  • Remove duplicate test block

Regarding Comment 6

Tags that store raw ValueToken and evaluate directly with evalToken() still need explicit resolveGroupedExpressionFilters() calls:

  • for.ts - collection property
  • case.ts - when values
  • tablerow.ts - collection property

Tags that wrap with new Value() get automatic recursive resolution via Value constructor.

Test Results

All 1537 tests pass ✅


Note: This PR is for demonstration purposes to discuss the architectural approach. The actual changes should be applied to PR #863 by @skynetigor.

cc @harttle @skynetigor - feedback welcome!

skynetigor and others added 14 commits March 23, 2026 17:27
…l-and-Loop-Tags' of https://github.com/skynetigor/liquidjs into 833_Support-Value-Expressions-as-Operands-in-Conditional-and-Loop-Tags

Made-with: Cursor

# Conflicts:
#	src/parser/tokenizer.ts
…l-and-Loop-Tags' of https://github.com/skynetigor/liquidjs into 833_Support-Value-Expressions-as-Operands-in-Conditional-and-Loop-Tags
…cenarios for enabled and disabled grouped expressions in case, for, if, unless tags, ensuring proper handling of expressions and error throwing for invalid syntax.
The readGroupedExpression() test suite was duplicated twice in the spec file. Removed the duplicate block to avoid redundant test execution.
Extract inline grouped expression variable extraction logic into a dedicated
function for consistency with other extractors (extractFilteredValueVariables,
extractPropertyAccessVariable).

This addresses PR harttle#863 comment 7 - improves code organization and
maintainability.
collection: ValueToken | GroupedExpressionToken

Addresses PR harttle#863 comment 5.
…lters

Addresses PR review comments 4, 6, 8, 9 - moves grouped expression evaluation
from parse-time resolution to render-time lazy evaluation following the
generator-based async/sync duality pattern used throughout liquidjs.

Key changes:
- Replace resolvedValue (Value instance) with resolvedFilters (Filter[])
- Rename resolveGroupedExpressions() to resolveGroupedExpressionFilters()
- Move evaluation logic to evalGroupedExpressionToken() at render time
- Build Filter instances at parse time (carry liquid reference for render)
- Evaluate expression and apply filters lazily via generators
- Add support for tablerow tag with grouped expressions
- Remove duplicate getFilter() method in Value class

Maintains proper layering (tokens → render → templates) and consistency
with Value.value() pattern. Filter resolution still happens at parse time
since it requires liquid.filters access, but actual evaluation is deferred
to render time.

Tags that store raw ValueToken (for, case when-values, tablerow) still need
explicit resolveGroupedExpressionFilters() calls. Tags that wrap with
new Value() get automatic recursive resolution via Value constructor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants