Skip to content

Conversation

@techouse
Copy link
Owner

@techouse techouse commented Jan 12, 2026

This pull request introduces a new overflow object representation for decoded lists that exceed the configured listLimit, ensuring correct handling and merging of large lists in query string decoding. It refactors internal utilities to support this overflow logic, updates decoding and merging behavior to recognize and process overflow objects, and adds comprehensive test coverage for these scenarios.

Overflow object implementation and utilities

  • Added Utils+Overflow.swift to define overflow object mechanics, including marking, checking, and managing the maximum index for overflowed lists. This enables lists that exceed listLimit to be represented as a dictionary with integer keys and a special overflow marker.
  • Refactored internal utilities (Utils+Combine.swift and Utils+Merge.swift) to use the new overflow object format when combining or merging lists that exceed the limit, ensuring consistent overflow handling throughout decoding and merging. [1] [2] [3] [4] [5]

Decoder and query parsing updates

  • Updated Decoder+ParseObject.swift and Decoder+ParseQuery.swift to create and propagate overflow objects when decoding lists that exceed listLimit, and to handle merging and normalization of overflow objects within parsed results. [1] [2]

Decoded object conversion and integration

  • Modified Qs+Decode.swift to convert overflow objects into standard string-keyed dictionaries for final output, ensuring decoded results remain accessible and consistent for consumers, and to merge overflow objects correctly when combining multiple parsed fragments. [1] [2] [3]

Test coverage for overflow behavior

  • Added and updated tests in both Swift and Objective-C test suites to verify correct handling of lists at or above the listLimit, including conversion to overflow objects and correct merging behavior. [1] [2] [3] [4] [5]

Miscellaneous

  • Updated the ReerKit dependency version for Linux in both Package.swift and Package@swift-5.10.swift. [1] [2]
  • Ensured overflow keys are ignored during dictionary traversal and object construction in decoding utilities. [1] [2]

Relates to GHSA-6rw7-vpxm-498p

Summary by CodeRabbit

  • New Features

    • Added overflow-aware representation for lists that exceed configured limits.
  • Improvements

    • List decoding now honors configurable list limits and converts oversized lists into a stable dictionary-like form.
    • Empty-bracket, duplicate and boundary list behaviors refined under listLimit and strict-null settings.
    • Merge/combination logic updated to preserve and propagate overflow metadata across merges.
  • Tests

    • Expanded tests covering list limits, overflow handling, merging, decoding, and edge cases.

✏️ Tip: You can customize this high-level summary in your review settings.

@techouse techouse self-assigned this Jan 12, 2026
@techouse techouse added the bug Something isn't working label Jan 12, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

📝 Walkthrough

Walkthrough

Adds overflow-aware list handling: combine/merge now accept a configurable listLimit, convert oversized arrays into overflow dictionaries with a hidden max-index key, preserve overflow metadata through merges, and decode overflow maps back into string-keyed objects during finalization.

Changes

Cohort / File(s) Summary
Overflow Infrastructure
Sources/QsSwift/Internal/Utils+Overflow.swift
Adds internal overflow key and helpers to detect, read, set, refresh, and mark per-dictionary overflow max index.
Combine Logic
Sources/QsSwift/Internal/Utils+Combine.swift
Adds combine(_:_ , listLimit:) overload that flattens inputs and returns an array when within limit or an overflow dictionary when exceeded; helpers to build/append overflow objects.
Merge Logic
Sources/QsSwift/Internal/Utils+Merge.swift
Propagates and updates overflow max indices during merges; preserves overflow semantics when merging arrays/dictionaries and overflow-wrapped structures.
Core Utilities
Sources/QsSwift/Internal/Utils.swift
Skips internal overflow metadata keys during deep-bridge traversal to avoid treating them as normal entries.
Decoder: Parse Paths
Sources/QsSwift/Internal/Decoder+ParseObject.swift, Sources/QsSwift/Internal/Decoder+ParseQuery.swift
Propagates listLimit into combine calls; bypasses overflow leaves and normalizes combine results into arrays or overflow-aware shapes.
Main Decode Handler
Sources/QsSwift/Qs+Decode.swift
Adds objectifyOverflow helper to stringify numeric keys and strip overflow metadata; converts overflow maps into standard [String: Any] during parse/merge.
Tests (Swift & ObjC)
Tests/QsObjCTests/ObjCDecodeTests.swift, Tests/QsSwiftTests/DecodeTests.swift, Tests/QsSwiftTests/UtilsTests.swift
New/updated tests covering listLimit behavior, empty-bracket handling, overflow semantics for combine/merge, and dictionary-based access for list-like results.
Package files
Package.swift, Package@swift-5.10.swift, Package.resolved
Dependency version bump and resolved originHash update (no API changes).

Sequence Diagram(s)

sequenceDiagram
    participant Parser as Decoder parse step
    participant Combine as Utils.combine(listLimit)
    participant Overflow as Utils::Overflow helpers
    participant Merge as Utils.merge
    participant Final as Qs+Decode finalizer

    Parser->>Combine: send parsed value(s) + listLimit
    Combine->>Overflow: flatten inputs, check count
    alt within limit
        Combine-->>Parser: return array ([Any?])
    else exceeds limit
        Combine->>Overflow: build overflow dict, set maxIndex
        Combine-->>Parser: return overflow dict
    end

    Parser->>Merge: merge combined item into accumulator
    Merge->>Overflow: detect/propagate overflow flags & maxIndex
    Merge-->>Parser: return merged (array/dict/overflow-aware dict)

    Parser->>Final: deliver merged structure
    Final->>Overflow: detect overflow map
    alt is overflow map
        Final->>Final: objectify (stringify numeric keys, remove overflow metadata)
        Final-->>Output: emit objectified dict
    else normal
        Final-->>Output: emit structure as-is
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement, test

Poem

🐰 I nibbled lists that grew too wide,
Turned spilling rows to keys that hide,
Counted limits, kept the max in sight,
Merged and stitched overflow back to right,
Hopping home with tidy bytes and pride. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and accurately describes the main change: enhancing Utils with overflow handling and list limit enforcement for query string decoding.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all major changes including overflow handling, decoder updates, test coverage, and dependencies.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 12, 2026

Codecov Report

❌ Patch coverage is 75.29412% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.37%. Comparing base (08fc3c0) to head (12dee9c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
Sources/QsSwift/Internal/Utils+Merge.swift 56.33% 31 Missing ⚠️
Sources/QsSwift/Internal/Utils+Combine.swift 87.50% 5 Missing ⚠️
Sources/QsSwift/Qs+Decode.swift 77.77% 4 Missing ⚠️
Sources/QsSwift/Internal/Decoder+ParseQuery.swift 85.71% 1 Missing ⚠️
Sources/QsSwift/Internal/Utils.swift 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #21      +/-   ##
==========================================
- Coverage   94.47%   93.37%   -1.11%     
==========================================
  Files          53       54       +1     
  Lines        2663     2823     +160     
==========================================
+ Hits         2516     2636     +120     
- Misses        147      187      +40     
Flag Coverage Δ
macos-15 93.30% <75.29%> (-1.18%) ⬇️
macos-26 93.37% <75.29%> (-1.11%) ⬇️
swift 93.37% <75.29%> (-1.11%) ⬇️
swift-6.1 93.30% <75.29%> (-1.18%) ⬇️
swift-6.2 93.37% <75.29%> (-1.11%) ⬇️
xcode-16.3 93.30% <75.29%> (-1.18%) ⬇️
xcode-26 93.37% <75.29%> (-1.11%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @Sources/QsSwift/Internal/Utils+Combine.swift:
- Around line 33-47: When combine(_:_:listLimit:) sees that first is an overflow
dictionary (isOverflow(dict)), appendOverflow(dict, value: second) currently
inserts second as a single element causing nested arrays; change the logic so
overflow merging preserves the same flattening semantics as appendCombineValue:
when appending into an overflow map, flatten arrays and append individual
elements (using appendCombineValue semantics), and represent nil as NSNull.
Update the overflow-append path (and the symmetric case around lines 68-79) to
iterate/flatten the incoming value and push elements into the overflow's
internal array rather than nesting the array as one element, ensuring
arrayToOverflowObject and isOverflow behavior remain consistent.

In @Sources/QsSwift/Internal/Utils+Overflow.swift:
- Around line 3-49: refreshOverflowMaxIndex currently only detects keys with
`key as? Int` and will miss bridged ObjC numeric keys (NSNumber); update
Utils.refreshOverflowMaxIndex to treat keys that are Int or NSNumber (e.g., if
let n = key as? Int ?? (key as? NSNumber)?.intValue) and compute the maxIndex
from those values, then call setOverflowMaxIndex(&dict, maxIndex) instead of
writing dict[overflowKey] directly to keep the write-path consistent; continue
skipping keys where isOverflowKey(key) is true.
🧹 Nitpick comments (2)
Sources/QsSwift/Internal/Utils+Combine.swift (1)

49-57: Avoid the map(Optional.some) allocation in a hot path.

arr.map(Optional.some) allocates an intermediate array; a simple loop can append without the extra allocation (especially relevant for Internal hot paths). As per coding guidelines, avoid unnecessary allocations in parsing/combining code.

Possible tweak
 } else if let arr = value as? [Any] {
-    array.append(contentsOf: arr.map(Optional.some))
+    array.reserveCapacity(array.count + arr.count)
+    for v in arr { array.append(v) }
 }
Sources/QsSwift/Internal/Utils+Merge.swift (1)

19-39: Overflow maxIndex should consider source’s declared overflowMaxIndex too (defensive).

In the array→dict merge branch, when source is overflow you set maxIndex based on observed keys. It’s safer to also take max(sourceMax, computedMax) to guard against stale/malformed inputs (or future changes that don’t populate all numeric keys). Based on learnings, keep max-index logic consistent.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08fc3c0 and 430f84c.

📒 Files selected for processing (10)
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Combine.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
🧰 Additional context used
📓 Path-based instructions (8)
Tests/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Preserve deterministic ordering in fixtures and tests by using OrderedDictionary; do not replace with [String: Any] where ordering matters

Files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
Tests/QsObjCTests/**/*.{m,mm,swift}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Tests/QsObjCTests/**/*.{m,mm,swift}: Add unit tests in QsObjCTests when features are bridged to ObjC
In ObjC tests, do not rely on NSDictionary enumeration order; explicitly sort when checking key order

Files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
Tests/**/*.{swift,m,mm}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Prefer explicit assertion helpers over broad equality when validating ordering or null semantics

Files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
**/*.{swift,h,m,mm}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use 4-space indentation across Swift and Objective-C sources

Files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
  • Sources/QsSwift/Internal/Utils+Combine.swift
**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Doc comments should be concise and note option interactions (e.g., decodeDotInKeys implies allowDots)

Files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
  • Sources/QsSwift/Internal/Utils+Combine.swift
Sources/QsSwift/Internal/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Sources/QsSwift/Internal/**/*.swift: In hot paths (parsing/encoding engine), avoid unnecessary allocations and do not introduce new regex use unless already present
If sort closure is nil and encode=false, retain traversal order; maintain stability when adding traversal logic
For large indices above listLimit, convert arrays to maps and keep logic consistent
Depth and parameter limits must remain O(length(query)); avoid quadratic regressions

Files:

  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
  • Sources/QsSwift/Internal/Utils+Combine.swift
Sources/QsSwift/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Sources/QsSwift/**/*.swift: Respect null semantics: use NSNull() for null-like values and Undefined() to omit keys; honor strictNullHandling and skipNulls flags
Do not swallow errors in core encode/decode; propagate as thrown Swift errors

Files:

  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
  • Sources/QsSwift/Internal/Utils+Combine.swift
Tests/QsSwiftTests/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Add unit tests in QsSwiftTests for new Swift options/behaviors

Files:

  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
🧠 Learnings (21)
📓 Common learnings
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : For large indices above listLimit, convert arrays to maps and keep logic consistent
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsObjCTests/**/*.{m,mm,swift} : Add unit tests in QsObjCTests when features are bridged to ObjC

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsSwiftTests/**/*.swift : Add unit tests in QsSwiftTests for new Swift options/behaviors

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsObjCTests/**/*.{m,mm,swift} : In ObjC tests, do not rely on NSDictionary enumeration order; explicitly sort when checking key order

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Mirror new Swift options in ObjC bridge classes (QsEncodeOptions, QsDecodeOptions) only when applicable to ObjC users

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : For large indices above listLimit, convert arrays to maps and keep logic consistent

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
  • Sources/QsSwift/Internal/Utils+Combine.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Keep Objective-C bridge wrappers thin, translating NSDictionary/NSArray/blocks to Swift equivalents without extra allocations

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/**/*.{swift,m,mm} : Prefer explicit assertion helpers over broad equality when validating ordering or null semantics

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsSwiftTests/Fixtures/Data/EndToEndTestCases.swift : For end-to-end cases, only mutate EndToEndTestCases.swift and use OrderedDictionary for canonical shapes

Applied to files:

  • Tests/QsObjCTests/ObjCDecodeTests.swift
  • Tests/QsSwiftTests/DecodeTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/**/*.swift : Respect null semantics: use NSNull() for null-like values and Undefined() to omit keys; honor strictNullHandling and skipNulls flags

Applied to files:

  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Bench/**/*.{swift} : Keep changes allocation-neutral where possible; benchmark if touching tight loops

Applied to files:

  • Sources/QsSwift/Internal/Utils.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : In hot paths (parsing/encoding engine), avoid unnecessary allocations and do not introduce new regex use unless already present

Applied to files:

  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.swift : In async helpers within the ObjC bridge, avoid captures that trigger Sendable warnings; keep closures minimal

Applied to files:

  • Sources/QsSwift/Internal/Utils.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : Depth and parameter limits must remain O(length(query)); avoid quadratic regressions

Applied to files:

  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Tests/QsSwiftTests/DecodeTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/**/*.swift : Preserve deterministic ordering in fixtures and tests by using OrderedDictionary; do not replace with [String: Any] where ordering matters

Applied to files:

  • Sources/QsSwift/Internal/Utils.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Qs.swift : When adding a new option or behavior, update the Swift option structs (EncodeOptions, DecodeOptions) in the public façade

Applied to files:

  • Sources/QsSwift/Internal/Utils.swift
  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/**/*.swift : Do not swallow errors in core encode/decode; propagate as thrown Swift errors

Applied to files:

  • Sources/QsSwift/Internal/Decoder+ParseQuery.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Maintain existing ObjC error domains and codes when introducing new failure modes

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Qs+Decode.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Bridge null semantics correctly to ObjC, returning/accepting NSError where appropriate and preserving NSNull vs omitted key behavior

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/DecodeTests.swift
  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Map Objective-C blocks to Swift closures by unwrapping and passing through without extra allocations

Applied to files:

  • Sources/QsSwift/Qs+Decode.swift
  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : If sort closure is nil and encode=false, retain traversal order; maintain stability when adding traversal logic

Applied to files:

  • Sources/QsSwift/Internal/Decoder+ParseObject.swift
🧬 Code graph analysis (6)
Sources/QsSwift/Internal/Utils.swift (1)
Sources/QsSwift/Internal/Utils+Overflow.swift (1)
  • isOverflowKey (35-38)
Sources/QsSwift/Internal/Utils+Merge.swift (1)
Sources/QsSwift/Internal/Utils+Overflow.swift (5)
  • isOverflowKey (35-38)
  • isOverflow (9-13)
  • setOverflowMaxIndex (20-23)
  • overflowMaxIndex (15-18)
  • markOverflow (25-33)
Tests/QsSwiftTests/DecodeTests.swift (3)
Sources/QsSwift/Qs+Decode.swift (1)
  • decode (34-39)
Sources/QsSwift/Internal/Utils+Decode.swift (1)
  • decode (12-39)
Sources/QsSwift/Models/DecodeOptions.swift (1)
  • decode (243-254)
Sources/QsSwift/Qs+Decode.swift (2)
Sources/QsSwift/Internal/Utils+Overflow.swift (2)
  • isOverflowKey (35-38)
  • isOverflow (9-13)
Sources/QsSwift/Internal/Utils+Merge.swift (1)
  • merge (15-321)
Sources/QsSwift/Internal/Decoder+ParseObject.swift (2)
Sources/QsSwift/Internal/Utils+Overflow.swift (1)
  • isOverflow (9-13)
Sources/QsSwift/Internal/Utils+Combine.swift (2)
  • combine (11-28)
  • combine (32-47)
Sources/QsSwift/Internal/Utils+Combine.swift (1)
Sources/QsSwift/Internal/Utils+Overflow.swift (4)
  • isOverflow (9-13)
  • markOverflow (25-33)
  • overflowMaxIndex (15-18)
  • setOverflowMaxIndex (20-23)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Swift tests (macos-15, Xcode 16.3, Swift 6.1)
  • GitHub Check: Swift tests (Ubuntu, Swift 6.2 — experimental)
  • GitHub Check: Swift tests (Ubuntu, Swift 6.1)
  • GitHub Check: Swift tests (macos-26, Xcode 26, Swift 6.2 — experimental)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Analyze (swift)
🔇 Additional comments (10)
Sources/QsSwift/Internal/Utils.swift (1)

106-106: LGTM! Overflow key filtering is correctly applied to both dictionary iteration paths.

The guards appropriately skip overflow metadata keys during deep bridging, ensuring they don't appear in the final [String: Any] output. This is consistent with the overflow tracking mechanism in Utils+Overflow.swift.

Also applies to: 117-117

Tests/QsObjCTests/ObjCDecodeTests.swift (1)

207-213: Good test coverage for overflow behavior with [] notation.

The test correctly verifies that when listLimit = 0, array notation falls back to dictionary representation with string keys. The assertions appropriately access keys individually rather than relying on enumeration order, which aligns with coding guidelines for ObjC tests.

Sources/QsSwift/Internal/Decoder+ParseQuery.swift (1)

202-209: Correct integration of listLimit-aware combine with proper type handling.

The cascade correctly handles all return types from the new Utils.combine(_:_:listLimit:) overload:

  • [Any?] arrays are normalized by mapping nil to NSNull
  • [Any] arrays are assigned directly
  • Overflow dictionaries (the else branch) are assigned as-is

The type check order is correct since [Any?] and [Any] are distinct types in Swift.

Sources/QsSwift/Internal/Decoder+ParseObject.swift (1)

58-70: Well-structured overflow-aware handling for [] root segments.

The implementation correctly:

  1. Preserves already-overflow structures without re-wrapping (line 58-59)
  2. Maintains existing allowEmptyLists behavior (line 60-63)
  3. Uses a unified combine-based approach that respects listLimit (lines 65-70)

The valueForCombine closure handles all leaf types appropriately before passing to Utils.combine, which will return either an array or overflow dictionary based on the limit. This aligns with the coding guideline to convert arrays to maps for large indices above listLimit.

Sources/QsSwift/Qs+Decode.swift (3)

213-224: Well-implemented objectifyOverflow helper for normalizing overflow dictionaries.

The closure efficiently converts overflow [AnyHashable: Any] dictionaries to [String: Any] by:

  • Using reserveCapacity to minimize reallocations
  • Filtering overflow keys via Utils.isOverflowKey
  • Properly converting Int keys to strings (preserving numeric indices)

This ensures overflow structures are converted to a standard dictionary format before being used in the result.


239-244: Correct first-parsed overflow handling as a fast path.

This branch appropriately handles the case where the first parsed value is an overflow dictionary, converting it via objectifyOverflow before setting it as the initial obj. This mirrors the existing fast path for [String: Any] maps on lines 235-238.


273-279: Consistent overflow handling during the merge phase.

The overflow branch correctly objectifies the overflow dictionary before merging, maintaining consistency with the list-to-indexed-map conversion pattern above it (lines 261-272). The merge result is properly cast and assigned.

Sources/QsSwift/Internal/Utils+Overflow.swift (1)

9-13: LGTM: overflow marker is minimal and avoids extra allocations.

The sentinel-key approach (OverflowKey + maxIndex) is lightweight and should be easy to strip during public “objectify” phases.

Also applies to: 15-23, 25-33

Tests/QsSwiftTests/UtilsTests.swift (1)

780-865: Nice coverage for listLimit overflow + propagation (and avoids order traps).

The tests validate both boundary conditions and that overflow metadata doesn’t interfere with consuming element values (filtering out overflow key before asserts).

Tests/QsSwiftTests/DecodeTests.swift (1)

558-562: LGTM: test expectations match the new “listLimit=0 yields map-like output” contract.

Switching to asDictString access and asserting specific numeric-string keys keeps these tests deterministic and aligned with the new overflow/objectification behavior. As per coding guidelines, this avoids relying on dictionary enumeration order.

Also applies to: 573-577, 936-963, 2240-2297, 2510-2527, 2925-2928

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
Sources/QsSwift/Internal/Utils+Overflow.swift (1)

18-21: Inconsistent overflowKey wrapping may cause lookup failures.

Line 20 wraps overflowKey in AnyHashable(overflowKey) for lookup, but lines 30 and 39 use dict[overflowKey] directly. Since OverflowKey is Hashable, both patterns should work due to Swift's dictionary subscript behavior, but consistency would be clearer.

More importantly, isOverflowKey (line 45) allocates a new AnyHashable on every call. Since this is called in hot paths (e.g., filtering overflow keys during merge), consider caching the AnyHashable wrapper or using a direct type check.

♻️ Suggested optimization for hot-path usage
     @usableFromInline
-    internal static let overflowKey = OverflowKey()
+    internal static let overflowKey = OverflowKey()
+    
+    @usableFromInline
+    internal static let overflowKeyHashable = AnyHashable(overflowKey)

     @inline(__always)
     @usableFromInline
     internal static func isOverflowKey(_ key: AnyHashable) -> Bool {
-        key == AnyHashable(overflowKey)
+        key == overflowKeyHashable
     }

Also applies to: 28-31, 43-46

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 430f84c and ede5dbc.

📒 Files selected for processing (4)
  • Sources/QsSwift/Internal/Utils+Combine.swift
  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Tests/QsSwiftTests/UtilsTests.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • Sources/QsSwift/Internal/Utils+Combine.swift
🧰 Additional context used
📓 Path-based instructions (7)
Sources/QsSwift/Internal/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Sources/QsSwift/Internal/**/*.swift: In hot paths (parsing/encoding engine), avoid unnecessary allocations and do not introduce new regex use unless already present
If sort closure is nil and encode=false, retain traversal order; maintain stability when adding traversal logic
For large indices above listLimit, convert arrays to maps and keep logic consistent
Depth and parameter limits must remain O(length(query)); avoid quadratic regressions

Files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
Sources/QsSwift/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Sources/QsSwift/**/*.swift: Respect null semantics: use NSNull() for null-like values and Undefined() to omit keys; honor strictNullHandling and skipNulls flags
Do not swallow errors in core encode/decode; propagate as thrown Swift errors

Files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
**/*.{swift,h,m,mm}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use 4-space indentation across Swift and Objective-C sources

Files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/UtilsTests.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Doc comments should be concise and note option interactions (e.g., decodeDotInKeys implies allowDots)

Files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/UtilsTests.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
Tests/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Preserve deterministic ordering in fixtures and tests by using OrderedDictionary; do not replace with [String: Any] where ordering matters

Files:

  • Tests/QsSwiftTests/UtilsTests.swift
Tests/QsSwiftTests/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Add unit tests in QsSwiftTests for new Swift options/behaviors

Files:

  • Tests/QsSwiftTests/UtilsTests.swift
Tests/**/*.{swift,m,mm}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Prefer explicit assertion helpers over broad equality when validating ordering or null semantics

Files:

  • Tests/QsSwiftTests/UtilsTests.swift
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : For large indices above listLimit, convert arrays to maps and keep logic consistent
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : For large indices above listLimit, convert arrays to maps and keep logic consistent

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/UtilsTests.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Keep Objective-C bridge wrappers thin, translating NSDictionary/NSArray/blocks to Swift equivalents without extra allocations

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Qs.swift : When adding a new option or behavior, update the Swift option structs (EncodeOptions, DecodeOptions) in the public façade

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Mirror new Swift options in ObjC bridge classes (QsEncodeOptions, QsDecodeOptions) only when applicable to ObjC users

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/**/*.swift : Respect null semantics: use NSNull() for null-like values and Undefined() to omit keys; honor strictNullHandling and skipNulls flags

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Maintain existing ObjC error domains and codes when introducing new failure modes

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : In hot paths (parsing/encoding engine), avoid unnecessary allocations and do not introduce new regex use unless already present

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Bridge null semantics correctly to ObjC, returning/accepting NSError where appropriate and preserving NSNull vs omitted key behavior

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{h,m,mm} : When exposing new enums or option flags to ObjC, keep naming consistent with existing cases (e.g., QsListFormatIndices)

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.swift : In async helpers within the ObjC bridge, avoid captures that trigger Sendable warnings; keep closures minimal

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsObjCTests/**/*.{m,mm,swift} : In ObjC tests, do not rely on NSDictionary enumeration order; explicitly sort when checking key order

Applied to files:

  • Sources/QsSwift/Internal/Utils+Merge.swift
  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsSwiftTests/**/*.swift : Add unit tests in QsSwiftTests for new Swift options/behaviors

Applied to files:

  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsObjCTests/**/*.{m,mm,swift} : Add unit tests in QsObjCTests when features are bridged to ObjC

Applied to files:

  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/**/*.{swift,m,mm} : Prefer explicit assertion helpers over broad equality when validating ordering or null semantics

Applied to files:

  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/**/*.swift : Preserve deterministic ordering in fixtures and tests by using OrderedDictionary; do not replace with [String: Any] where ordering matters

Applied to files:

  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Tests/QsSwiftTests/Fixtures/Data/EndToEndTestCases.swift : For end-to-end cases, only mutate EndToEndTestCases.swift and use OrderedDictionary for canonical shapes

Applied to files:

  • Tests/QsSwiftTests/UtilsTests.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Bench/**/*.{swift} : Keep changes allocation-neutral where possible; benchmark if touching tight loops

Applied to files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
🧬 Code graph analysis (1)
Sources/QsSwift/Internal/Utils+Merge.swift (1)
Sources/QsSwift/Internal/Utils+Overflow.swift (4)
  • isOverflow (17-21)
  • overflowMaxIndex (23-26)
  • setOverflowMaxIndex (28-31)
  • markOverflow (33-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Swift tests (macos-26, Xcode 26, Swift 6.2 — experimental)
  • GitHub Check: Swift tests (macos-15, Xcode 16.3, Swift 6.1)
  • GitHub Check: Swift tests (Ubuntu, Swift 6.1)
  • GitHub Check: Swift tests (Ubuntu, Swift 6.2 — experimental)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Analyze (swift)
🔇 Additional comments (13)
Sources/QsSwift/Internal/Utils+Overflow.swift (1)

1-58: Well-structured overflow utilities.

The overflow infrastructure is cleanly designed with appropriate visibility modifiers and inline hints. The OverflowKey marker type prevents collision with user keys.

Tests/QsSwiftTests/UtilsTests.swift (6)

780-805: Good boundary condition coverage for listLimit.

The test covers under-limit, exact-limit, over-limit, and zero-limit cases. The assertions verify both the overflow flag and the dictionary contents at expected indices.


807-821: Validates append-to-overflow semantics.

The test correctly verifies that combining a scalar with an existing overflow object appends at the next available index (maxIndex + 1).


823-845: Comprehensive test for array flattening and null semantics.

The test validates that arrays are flattened when appended to overflow objects, and correctly verifies that nil elements are converted to NSNull. This aligns with the coding guidelines for null semantics.


847-869: Tests bidirectional overflow merging.

The test validates merge behavior in both directions: merging a scalar into an overflow object and merging an overflow source into a primitive target. Both correctly preserve the overflow flag.


871-888: Validates maxIndex preservation through array merges.

The test correctly verifies that when an overflow dictionary is merged into an array target, the overflow metadata (maxIndex) is preserved, allowing subsequent appends to use the correct index.


890-902: Thorough test for mixed key types.

The test validates that refreshOverflowMaxIndex correctly handles mixed key types (Int, NSNumber, and String), computing the max from only numeric keys while excluding the overflow marker key.

Sources/QsSwift/Internal/Utils+Merge.swift (6)

19-42: Correct overflow propagation when merging array target with dict source.

The logic correctly tracks maxIndex from both the target array and source dictionary keys, propagates overflow metadata when the source is an overflow dictionary, and respects null semantics by converting nil to NSNull().


44-60: Correct overflow extension when merging dict target with array source.

When the target is an overflow dictionary, elements from the source array are correctly appended using incrementing indices starting from maxIndex + 1, with proper null semantics.


163-180: Handles overflow dict target with arbitrary source types.

The logic correctly extends overflow dictionaries with both sequence and scalar sources, filtering Undefined values and updating the maxIndex metadata.


205-241: Complex but correct handling of overflow source with various target types.

The logic correctly handles three cases:

  1. Array target: merges entries preserving both sets of indices
  2. Nil target: wraps as NSNull at index 0, shifts source indices by 1
  3. Scalar target: places at index 0, shifts source indices

The newMax = sourceMax + 1 calculation correctly accounts for the index shift.


288-320: Comprehensive overflow propagation in the main merge path.

The logic correctly:

  1. Detects overflow status on both target and source
  2. Tracks the maximum numeric index during iteration
  3. Combines computed max with source's overflow metadata
  4. Sets overflow metadata on the result when either side is overflow

This ensures overflow semantics are preserved through recursive merges.


1-335: Overflow-aware merge logic is well-integrated.

The merge function correctly handles all combinations of overflow and non-overflow targets/sources, preserving metadata through the merge hierarchy. The implementation aligns with the learning that "for large indices above listLimit, convert arrays to maps and keep logic consistent."

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
Sources/QsSwift/Internal/Utils+Overflow.swift (1)

48-57: Consider adding a brief doc comment for the -1 sentinel semantics.

The function sets maxIndex = -1 when no integer keys exist, which is a valid sentinel but could benefit from a short inline comment clarifying this represents "no valid indices found."

📝 Suggested documentation
     @usableFromInline
+    /// Scans non-overflow keys to compute the maximum integer index and stores it.
+    /// Sets -1 if no integer keys are present.
     internal static func refreshOverflowMaxIndex(_ dict: inout [AnyHashable: Any]) {
         var maxIndex = -1
         for key in dict.keys where !isOverflowKey(key) {
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ede5dbc and ef812dc.

📒 Files selected for processing (4)
  • Package.resolved
  • Package.swift
  • Package@swift-5.10.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{swift,h,m,mm}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use 4-space indentation across Swift and Objective-C sources

Files:

  • Package@swift-5.10.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Package.swift
**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Doc comments should be concise and note option interactions (e.g., decodeDotInKeys implies allowDots)

Files:

  • Package@swift-5.10.swift
  • Sources/QsSwift/Internal/Utils+Overflow.swift
  • Package.swift
Sources/QsSwift/Internal/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Sources/QsSwift/Internal/**/*.swift: In hot paths (parsing/encoding engine), avoid unnecessary allocations and do not introduce new regex use unless already present
If sort closure is nil and encode=false, retain traversal order; maintain stability when adding traversal logic
For large indices above listLimit, convert arrays to maps and keep logic consistent
Depth and parameter limits must remain O(length(query)); avoid quadratic regressions

Files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
Sources/QsSwift/**/*.swift

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Sources/QsSwift/**/*.swift: Respect null semantics: use NSNull() for null-like values and Undefined() to omit keys; honor strictNullHandling and skipNulls flags
Do not swallow errors in core encode/decode; propagate as thrown Swift errors

Files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : For large indices above listLimit, convert arrays to maps and keep logic consistent
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Internal/**/*.swift : For large indices above listLimit, convert arrays to maps and keep logic consistent

Applied to files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsSwift/Qs.swift : When adding a new option or behavior, update the Swift option structs (EncodeOptions, DecodeOptions) in the public façade

Applied to files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Keep Objective-C bridge wrappers thin, translating NSDictionary/NSArray/blocks to Swift equivalents without extra allocations

Applied to files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Bench/**/*.{swift} : Keep changes allocation-neutral where possible; benchmark if touching tight loops

Applied to files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
📚 Learning: 2025-10-13T21:33:37.731Z
Learnt from: CR
Repo: techouse/qs-swift PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-13T21:33:37.731Z
Learning: Applies to Sources/QsObjC/**/*.{swift,h,m,mm} : Bridge null semantics correctly to ObjC, returning/accepting NSError where appropriate and preserving NSNull vs omitted key behavior

Applied to files:

  • Sources/QsSwift/Internal/Utils+Overflow.swift
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Swift tests (macos-26, Xcode 26, Swift 6.2 — experimental)
  • GitHub Check: Swift tests (macos-15, Xcode 16.3, Swift 6.1)
  • GitHub Check: Swift tests (Ubuntu, Swift 6.2 — experimental)
  • GitHub Check: Swift tests (Ubuntu, Swift 6.1)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Analyze (swift)
🔇 Additional comments (7)
Sources/QsSwift/Internal/Utils+Overflow.swift (4)

3-7: LGTM!

Good use of an empty struct as a sentinel key type. This ensures no collision with user-provided keys (strings, integers, etc.) while remaining Hashable and Sendable for thread-safe dictionary operations.


9-15: LGTM!

The check order (native Int first, then NSNumber fallback) is correct. Note that NSNumber.intValue truncates floats and converts bools, which is acceptable behavior for array index extraction in this context.


17-31: LGTM!

The detection and accessor functions are concise and efficient. The inout parameter for setOverflowMaxIndex correctly enables in-place mutation without extra allocations.


33-41: LGTM!

The dictionary copy is necessary here for the immutable return semantics. Since this function is called only when overflow conditions are detected (not the common path), the allocation is justified.

Package.swift (1)

15-18: LGTM!

The ReerKit version bump is consistent with Package@swift-5.10.swift, ensuring both Swift toolchain versions resolve to the same dependency version on Linux.

Package.resolved (1)

1-3: LGTM!

The originHash update reflects the dependency manifest changes. Note that ReerKit doesn't appear in the pins because it's conditionally included only on Linux (#if os(Linux)), and this resolved file was generated on a non-Linux platform.

Package@swift-5.10.swift (1)

16-18: These are newly created package files, not a version update.

Package@swift-5.10.swift and Package.swift were added in this commit as new files with ReerKit 1.2.2, not updated from a prior version. Both files correctly use 4-space indentation and maintain consistent Linux-only conditional dependency inclusion.

Likely an incorrect or invalid review comment.

@techouse techouse merged commit 0ff7ddd into main Jan 12, 2026
12 of 14 checks passed
@techouse techouse deleted the fix/qs-cve branch January 12, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant