Refactor large parser modules into smaller components under 400 lines (#223)#259
Refactor large parser modules into smaller components under 400 lines (#223)#259leynos wants to merge 25 commits into
Conversation
- Extract rule-body term classification into a dedicated module `rule/classification.rs`. - Move S-expression formatting for Expr into a separate `expr/sexpr.rs` module. - Split Pratt parser postfix parsing, delay-postfix, and diff-marker handling into separate files under `expression/pratt/`. - Remove inline implementations and validations, organizing parser logic into coherent units. - Revamp expression parser tests to use fixture modules, improving maintainability. This refactor improves code organization, readability, and test structure without changing external behavior. Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
Refactor large parser modules into smaller components under 400 linesThis PR completes the planned refactor to split oversized parser modules to satisfy the 400-line local maintainability guideline (closes issue Key file size reductions (approx.)
Core refactor details
Supporting changes
Behaviour and API preservation
Review items and follow-ups
Reference to design/execplan
Testing guidance
WalkthroughExtract parser responsibilities into focused modules: move S-expression rendering to ChangesParser refactor cohort
Sequence Diagram sequenceDiagram
participant Pratt as Pratt parser
participant Postfix as postfix.rs
participant Diff as diff.rs
participant Delay as delay.rs
Pratt->>Postfix: parse_postfix(lhs)
Postfix->>Diff: handle_diff_marker()
Postfix->>Delay: parse_delay_postfix()
Postfix-->>Pratt: final Expr (AtomDiff/AtomDelay applied)
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
Reviewer's GuideRefactors parser internals by extracting S-expression formatting, rule-body classification, and Pratt postfix parsing into dedicated modules, and reworks expression tests around a reusable fixtures system without changing observable parsing behavior. Sequence diagram for the new rule body term parsing pipelinesequenceDiagram
participant RuleBodyExpression
participant RuleClassificationModule as classification
participant PatternParser as parse_pattern
participant ExpressionParser as parse_expression
participant AggregationLogic as aggregation_tracking
participant Errors as errors_vec
RuleBodyExpression->>RuleClassificationModule: parse_rule_body_term(raw, literal_span, first_aggregation_span, errors)
alt raw contains_assignment
RuleClassificationModule->>PatternParser: parse_pattern(parts.pattern)
PatternParser-->>RuleClassificationModule: Result_Pattern_or_errors
alt pattern_ok
RuleClassificationModule->>ExpressionParser: parse_expression(parts.value)
ExpressionParser-->>RuleClassificationModule: Result_Expr_or_errors
alt value_ok
RuleClassificationModule-->>RuleBodyExpression: Some_RuleBodyTerm_Assignment
else value_errors
RuleClassificationModule->>Errors: append(shifted_errors)
RuleClassificationModule-->>RuleBodyExpression: None
end
else pattern_errors
RuleClassificationModule->>Errors: append(shifted_errors)
RuleClassificationModule-->>RuleBodyExpression: None
end
else raw_is_expression
RuleClassificationModule->>ExpressionParser: parse_expression(trimmed_raw)
ExpressionParser-->>RuleClassificationModule: Result_Expr_or_errors
alt expr_ok
RuleClassificationModule->>AggregationLogic: classify_expression(expr, ctx)
AggregationLogic-->>RuleClassificationModule: Option_RuleBodyTerm
RuleClassificationModule-->>RuleBodyExpression: Option_RuleBodyTerm
else expr_errors
RuleClassificationModule->>Errors: append(errors)
RuleClassificationModule-->>RuleBodyExpression: None
end
end
Class diagram for rule body classification and Expr S-expression formattingclassDiagram
class Expr {
+to_sexpr() String
}
class Literal {
}
class Pattern {
+to_source() String
}
class MatchArm {
pattern Pattern
body Expr
}
class RuleBodyTerm {
}
class RuleAssignment {
pattern Pattern
value Expr
}
class RuleAggregation {
project Expr
key Expr
source AggregationSource
}
class RuleForLoop {
pattern Pattern
iterable Expr
guard Expr
body_terms Vec_RuleBodyTerm_
}
class AggregationSource {
<<enum>>
GroupBy
LegacyAggregate
}
class ClassificationContext {
-literal_span Span
-first_aggregation_span Option_Span_
-errors Vec_SimpleSyntaxKind__
}
class ForLoopComponents {
pattern Pattern
iterable Expr
guard Option_Expr_
body Expr
}
class RuleClassifier {
+parse_rule_body_term(raw String, literal_span Span, first_aggregation_span Option_Span_, errors Vec_SimpleSyntaxKind__) Option_RuleBodyTerm_
-parse_assignment(parts AssignmentParts, literal_span Span) Result_Option_RuleBodyTerm__Vec_SimpleSyntaxKind___
-classify_expression(expr Expr, ctx ClassificationContext) Option_RuleBodyTerm_
-classify_aggregation_with_tracking(args Vec_Expr_, source AggregationSource, ctx ClassificationContext) Option_RuleBodyTerm_
-classify_for_loop(components ForLoopComponents, ctx ClassificationContext) RuleBodyTerm
-classify_for_body_with_aggregation_tracking(body Expr, ctx ClassificationContext) Vec_RuleBodyTerm_
-aggregation_source_for(name String) Option_AggregationSource_
-invocation_aggregation_source(callee Expr) Option_AggregationSource_
-validate_aggregation(term RuleBodyTerm, literal_span Span, first_aggregation_span Option_Span_, errors Vec_SimpleSyntaxKind__) bool
-aggregation_arity_error(literal_span Span, source AggregationSource) Vec_SimpleSyntaxKind__
-multiple_aggregations_error(first_span Span, second_span Span) SimpleSyntaxKind
}
Expr --> Literal
Expr --> Pattern
Expr --> MatchArm
RuleBodyTerm <.. RuleAssignment
RuleBodyTerm <.. RuleAggregation
RuleBodyTerm <.. RuleForLoop
RuleForLoop "*" o-- "body_terms" RuleBodyTerm
RuleAggregation --> AggregationSource
RuleClassifier ..> ClassificationContext
RuleClassifier ..> ForLoopComponents
RuleClassifier ..> RuleBodyTerm
RuleClassifier ..> RuleAggregation
RuleClassifier ..> RuleAssignment
ClassificationContext --> Span
ClassificationContext --> AggregationSource
ForLoopComponents --> Pattern
ForLoopComponents --> Expr
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. src/parser/tests/expression/fixtures/errors.rs Comment on lines +217 to +232 fn collection_error_cases() -> Vec<CountedErrorCase> {
vec![
CountedErrorCase {
src: "[1, 2",
min_errs: 1,
},
CountedErrorCase {
src: "{a: 1",
min_errs: 1,
},
CountedErrorCase {
src: "{a, b}",
min_errs: 1,
},
]
}❌ New issue: Code Duplication |
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. src/parser/expression/pratt.rs Comment on file use chumsky::error::Simple;
use crate::parser::ast::{Expr, StringLiteral};
use crate::parser::span_utils::parse_u32_decimal;❌ New issue: Code Duplication |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Share the setup and teardown flow used by the Pratt parser's struct literal activation and suspension helpers. Keep the existing public helper signatures and delegate their state changes through one private scope method.
Default `CARGO` to the executable found on `PATH`, with a fallback to the standard Rustup installation path under `HOME`. This lets hook environments that omit the Cargo bin directory still run the repository Makefile targets.
Add a private helper for expression parser error cases that all expect a single minimum error. Keep the existing case order and fixture function signatures while removing repeated `CountedErrorCase` construction.
|
@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph. If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced. Code Duplicationsrc/parser/tests/expression/fixtures/errors.rs: What lead to degradation?The module contains 4 functions with similar structure: collection_error_cases,control_flow_error_cases,operator_error_cases,postfix_counted_error_cases Why does this problem occur?Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health. How to fix it?A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More |
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/parser/ast/rule/classification.rs`:
- Line 61: The check that treats missing assignment values uses
parts.value.is_empty(), which misses whitespace-only values like "x = ";
update the logic to trim the string before checking emptiness (e.g., use
parts.value.trim().is_empty()) so that the code path in the classification logic
(where parts.value is inspected) treats whitespace-only assignments as missing
expressions and triggers the targeted diagnostic instead of falling through to a
generic parse error.
In `@src/parser/tests/expression/fixtures/valid/postfix.rs`:
- Around line 9-67: Add two happy-path fixtures to the
postfix_expression_cases() vec: one for the apostrophe diff postfix (e.g., src
"e'") and one for the delay postfix (e.g., src "f-<1>"), each as an
ExpressionCase entry; set their expected AST using the same test helper pattern
used elsewhere (e.g., postfix_diff(var("e")) and postfix_delay(var("f"),
lit_num("1")) or the equivalent helper names in the tests) so the postfix parser
branches exercised by src/parser/expression/pratt/postfix.rs (apostrophe diff
handling and -<...> delay handling) are asserted to succeed and cannot regress
silently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0ae55951-bb4d-44a2-a93e-b1901d4665ef
📒 Files selected for processing (18)
Makefilesrc/parser/ast/expr.rssrc/parser/ast/expr/sexpr.rssrc/parser/ast/rule.rssrc/parser/ast/rule/classification.rssrc/parser/expression/pratt.rssrc/parser/expression/pratt/delay.rssrc/parser/expression/pratt/diff.rssrc/parser/expression/pratt/postfix.rssrc/parser/tests/expression.rssrc/parser/tests/expression/fixtures.rssrc/parser/tests/expression/fixtures/errors.rssrc/parser/tests/expression/fixtures/valid.rssrc/parser/tests/expression/fixtures/valid/basic.rssrc/parser/tests/expression/fixtures/valid/collections.rssrc/parser/tests/expression/fixtures/valid/control_flow.rssrc/parser/tests/expression/fixtures/valid/postfix.rssrc/parser/tests/expression/fixtures/valid/structured.rs
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
@coderabbitai please create new GitHub issues for the following: Out-of-scope: GitHub issues requiredDocstring Coverage (
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 88
Both include backlinks to PR |
…ule docs Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/parser/expression/pratt/postfix.rs`:
- Around line 171-188: The new tests miss exercising the diff and delay branches
in parse_postfix, so add unit tests that call parse_postfix (via
parse_expression) to cover the "'" (diff) postfix and the "-<" (delay) postfix,
including a test that sets up a pending diff and then ensures a delay is
rejected (verifying the guard that rejects delay while a diff is pending);
specifically add tests that assert the parsed AST or error messages for the "'"
and "-<" cases and one that confirms parse_postfix returns the expected error
when a delay is attempted while a diff is pending, referencing parse_postfix,
diff postfix, and delay postfix in your assertions.
- Around line 163-166: The module-wide Clippy suppression on the tests module is
too broad; remove the inner attribute `#![expect(clippy::expect_used, ...)]`
from the `mod tests` declaration and instead add item-level
`#[expect(clippy::expect_used, reason = "...")]` attributes to each test
function that calls `expect()`/`expect_err()` (for example
`qualified_callee_uses_call_postfix` and `trailing_argument_comma_is_rejected`)
so the lint is narrowly scoped to only those test items.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 79925021-05af-4cec-8d42-9af29b36a9d4
📒 Files selected for processing (1)
src/parser/expression/pratt/postfix.rs
Add focused `parse_expression` tests for the Pratt postfix diff and delay paths, including the pending-diff guard before delay parsing. Narrow the `expect_used` Clippy expectations to the individual test cases that need them instead of suppressing the whole test module.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/parser/expression/pratt/postfix.rs`:
- Around line 151-155: Capture the separator token's span before calling
self.ts.next_tok() and use that span when calling self.ts.push_error so the
diagnostic points at the comma instead of `)`/EOF; specifically, in the postfix
parsing code around the trailing-comma check, call something like let sep_span =
self.ts.peek_span().unwrap_or_else(|| self.ts.eof_span()) (or an equivalent that
inspects the separator) before invoking self.ts.next_tok(), then pass sep_span
into self.ts.push_error(sep_span, "unexpected trailing comma in argument list")
instead of using the later peek_span()/eof_span.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5d60a935-9967-447d-8e3e-02cc15596718
📒 Files selected for processing (1)
src/parser/expression/pratt/postfix.rs
Capture the comma span before consuming it in Pratt postfix argument parsing, then use that span for the trailing-comma diagnostic. Update the call parsing regression expectation so it verifies the diagnostic now points at the comma rather than the closing parenthesis.
Capture consumed postfix separator spans explicitly and report trailing argument commas at the comma token. Remove the defensive diff-marker EOF fallback so the helper exposes the fallible token consume directly. Strengthen parser tests by checking the wrapped diff expression, assignment pattern and value details, and S-expression rendering beside snapshots.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Assert the trailing-comma diagnostic span, unwrap the diff postfix AST to check the completed call it wraps, and add a direct expected rendering beside the collection S-expression snapshot.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/parser/ast/rule/classification.rs (1)
281-281:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMove the Clippy expectation to individual test items.
The
#![expect(clippy::expect_used, ...)]inner attribute applies to the entiremod testsblock, which violates the coding guideline requiring narrowly scoped lint suppressions. Apply#[expect(clippy::expect_used, reason = "...")]to each test function that uses.expect()instead.Proposed fix
#[cfg(test)] mod tests { - #![expect(clippy::expect_used, reason = "tests assert exact parser output")] - use super::*; use chumsky::error::SimpleReason; fn span_for(src: &str) -> Span { 0..src.len() } #[test] + #[expect(clippy::expect_used, reason = "test asserts exact parser output")] fn assignment_literal_becomes_assignment_term() { // ... } #[test] + #[expect(clippy::expect_used, reason = "test asserts exact parser output")] fn second_aggregation_reports_error() { // ... } }As per coding guidelines: "Only narrowly scoped
#[expect(lint, reason = "...")]is allowed. No lint groups, no blanket or file-wide suppression."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/ast/rule/classification.rs` at line 281, The file currently places the inner attribute #![expect(clippy::expect_used, reason = "...")] at the top of the tests module; change this to apply the expect lint to each test function that actually calls .expect() instead: remove the module-level #![expect(...)] and add #[expect(clippy::expect_used, reason = "...")] directly above every #[test] fn (inside mod tests) that uses .expect() so the suppression is narrowly scoped to those test items only.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/parser/ast/rule/classification.rs`:
- Line 281: The file currently places the inner attribute
#![expect(clippy::expect_used, reason = "...")] at the top of the tests module;
change this to apply the expect lint to each test function that actually calls
.expect() instead: remove the module-level #![expect(...)] and add
#[expect(clippy::expect_used, reason = "...")] directly above every #[test] fn
(inside mod tests) that uses .expect() so the suppression is narrowly scoped to
those test items only.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 301a4613-1ca0-4596-843e-4ad65d9c268b
📒 Files selected for processing (5)
src/parser/ast/expr/sexpr.rssrc/parser/ast/rule/classification.rssrc/parser/expression/pratt/diff.rssrc/parser/expression/pratt/postfix.rstests/expression_var_and_call.rs
Move the `clippy::expect_used` expectation from the whole classification test module to the individual tests that call `expect`. Keep the lint suppression scoped to the exact assertions that need it.
Expand expression fixture module documentation so each fixture group states its role in the parser test suite and how it relates to the shared fixture aggregators. Add direct Pratt helper coverage for diff-marker error paths and delay postfix boundary parsing, including the maximum `u32` delay and invalid delay values.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
src/parser/tests/expression/fixtures/valid.rs (1)
14-29: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winAdd Rustdoc to exported fixture entrypoints.
Document each
pub(super)function with///so the fixture contract is explicit in generated docs and module navigation.As per coding guidelines: "Document public APIs in Rust using Rustdoc comments (
///), so documentation can be generated withcargo doc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/tests/expression/fixtures/valid.rs` around lines 14 - 29, The three exported fixture entrypoints (pub(super) functions expression_cases, invalid_for_loop_sources, and literal_cases) lack Rustdoc; add concise /// comments above each function describing its purpose and returned value (e.g., that expression_cases returns combined ExpressionCase fixtures, invalid_for_loop_sources returns the array of invalid for-loop source strings, literal_cases returns literal ExpressionCase fixtures) so the fixture contract is explicit in generated docs and module navigation.src/parser/tests/expression/fixtures/valid/basic.rs (1)
10-83: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winAdd Rustdoc to exported basic fixture functions.
Document
basic_expression_cases,invalid_for_loop_sources, andliteral_caseswith///comments that define intent and return expectations.As per coding guidelines: "Document public APIs in Rust using Rustdoc comments (
///), so documentation can be generated withcargo doc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/tests/expression/fixtures/valid/basic.rs` around lines 10 - 83, Add Rustdoc comments (///) above the three fixture functions basic_expression_cases, invalid_for_loop_sources, and literal_cases describing their purpose and what they return (e.g., "Returns test cases for basic expressions as Vec<ExpressionCase>", "Returns invalid for-loop source strings as [&'static str; 4]", "Returns literal expression cases as Vec<ExpressionCase>"). Use concise intent sentences and a brief `# Returns` line for each function so cargo doc can generate accurate documentation.src/parser/tests/expression/fixtures/valid/structured.rs (1)
11-69: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winDocument the exported fixture builder with Rustdoc.
Add a
///comment abovestruct_and_closure_casesthat states the covered syntax groups and return contract.As per coding guidelines: "Document public APIs in Rust using Rustdoc comments (
///), so documentation can be generated withcargo doc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/tests/expression/fixtures/valid/structured.rs` around lines 11 - 69, Add a Rustdoc comment above the pub(super) function struct_and_closure_cases describing what syntax the fixture covers (struct expressions, tuple structs/fields, closures, tuples, nested expressions) and the return contract (returns Vec<ExpressionCase> of valid expression fixtures used by tests). Mention any important semantics callers should know (e.g., each ExpressionCase contains src and expected AST). Place the comment immediately above the struct_and_closure_cases declaration so it appears in generated docs.src/parser/tests/expression/fixtures/valid/control_flow.rs (1)
13-17: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winDocument the exported control-flow fixture entrypoint.
Add a
///comment describing the fixture groups included and ordering behaviour.As per coding guidelines: "Document public APIs in Rust using Rustdoc comments (
///), so documentation can be generated withcargo doc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/tests/expression/fixtures/valid/control_flow.rs` around lines 13 - 17, Add a Rustdoc comment above the exported function control_flow_expression_cases describing that it returns a Vec<ExpressionCase> composed by first including all if_expression_cases() and then appending match_and_for_expression_cases(), and note that ordering is significant (if-cases first, then match/for cases). Mention the fixture groups included (if, match, for) and the ordering behaviour so cargo doc will show the intent for consumers.src/parser/tests/expression/fixtures/valid/collections.rs (1)
11-75: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winDocument the exported collection fixture API.
Add a
///doc comment tocollection_expression_casesthat states covered literal forms and expected usage.As per coding guidelines: "Document public APIs in Rust using Rustdoc comments (
///), so documentation can be generated withcargo doc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/tests/expression/fixtures/valid/collections.rs` around lines 11 - 75, Add a Rustdoc comment (///) immediately above the pub(super) fn collection_expression_cases() describing the fixture's API: list the literal forms covered (empty and numeric vectors like "[]", "[1]", "[1, 2]", trailing-comma variants like "[1,]" and "[1, 2,]", element expressions like "[x, y + 1]"; and map literals "{}", "{a: 1}", "{a: 1,}", "{x: y, z: w}"), state that it returns Vec<ExpressionCase> for use in parser tests, and give a short example or note on how tests should consume the function (e.g., call to populate parameterized test cases). Ensure the comment is a /// Rustdoc placed immediately above collection_expression_cases so it appears in generated docs.src/parser/tests/expression/fixtures.rs (1)
12-58: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winAdd Rustdoc for exported fixture types and accessors.
Document each
pub(super)struct and function with///so callers can rely on explicit field and behaviour contracts.As per coding guidelines: "Document public APIs in Rust using Rustdoc comments (
///), so documentation can be generated withcargo doc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/tests/expression/fixtures.rs` around lines 12 - 58, Add Rustdoc comments for each exported fixture type and accessor: document the structs ExpressionCase, CountedErrorCase, SpannedErrorCase, and PostfixErrorCase (including brief descriptions of each public field: src, expected, min_errs, msg, start, end, unclosed) and document the accessor functions expression_cases, invalid_for_loop_sources, literal_cases, error_cases, match_pattern_error_cases, and postfix_error_cases to state their return types and that they delegate to valid:: or errors:: helpers. Ensure each doc comment uses /// and clearly states the contract/intent (what callers can expect from the returned values and when/why to use each fixture).
♻️ Duplicate comments (1)
src/parser/tests/expression/fixtures/valid/postfix.rs (1)
117-123: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winAdd Rustdoc to
postfix_expression_cases.Document this exported fixture entrypoint with
///to define its scope and ordering guarantees.As per coding guidelines: "Document public APIs in Rust using Rustdoc comments (
///), so documentation can be generated withcargo doc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/parser/tests/expression/fixtures/valid/postfix.rs` around lines 117 - 123, Add a Rustdoc comment for the exported fixture entrypoint function postfix_expression_cases to describe its purpose, scope and any ordering guarantees for the returned cases; update the function signature area (the pub(super) fn postfix_expression_cases() -> Vec<ExpressionCase> declaration) to be preceded by a /// doc comment that briefly explains this fixture, what categories it composes (field_and_method_call_cases, call_and_slice_cases, diff_marker_cases, delay_cases), and that callers can rely on the returned Vec ordering as defined by the appended extensions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/parser/expression/pratt/delay.rs`:
- Around line 54-56: Add a module-level doc comment for the test module named
`mod tests` in this file: insert a `//!` comment immediately inside the `mod
tests {` block that briefly explains the module's purpose and what aspects of
`delay` parsing it covers (e.g., unit tests for Pratt parser delay expression
handling, edge cases, and expected error conditions) so the module complies with
the guideline requiring a module-level comment.
---
Outside diff comments:
In `@src/parser/tests/expression/fixtures.rs`:
- Around line 12-58: Add Rustdoc comments for each exported fixture type and
accessor: document the structs ExpressionCase, CountedErrorCase,
SpannedErrorCase, and PostfixErrorCase (including brief descriptions of each
public field: src, expected, min_errs, msg, start, end, unclosed) and document
the accessor functions expression_cases, invalid_for_loop_sources,
literal_cases, error_cases, match_pattern_error_cases, and postfix_error_cases
to state their return types and that they delegate to valid:: or errors::
helpers. Ensure each doc comment uses /// and clearly states the contract/intent
(what callers can expect from the returned values and when/why to use each
fixture).
In `@src/parser/tests/expression/fixtures/valid.rs`:
- Around line 14-29: The three exported fixture entrypoints (pub(super)
functions expression_cases, invalid_for_loop_sources, and literal_cases) lack
Rustdoc; add concise /// comments above each function describing its purpose and
returned value (e.g., that expression_cases returns combined ExpressionCase
fixtures, invalid_for_loop_sources returns the array of invalid for-loop source
strings, literal_cases returns literal ExpressionCase fixtures) so the fixture
contract is explicit in generated docs and module navigation.
In `@src/parser/tests/expression/fixtures/valid/basic.rs`:
- Around line 10-83: Add Rustdoc comments (///) above the three fixture
functions basic_expression_cases, invalid_for_loop_sources, and literal_cases
describing their purpose and what they return (e.g., "Returns test cases for
basic expressions as Vec<ExpressionCase>", "Returns invalid for-loop source
strings as [&'static str; 4]", "Returns literal expression cases as
Vec<ExpressionCase>"). Use concise intent sentences and a brief `# Returns` line
for each function so cargo doc can generate accurate documentation.
In `@src/parser/tests/expression/fixtures/valid/collections.rs`:
- Around line 11-75: Add a Rustdoc comment (///) immediately above the
pub(super) fn collection_expression_cases() describing the fixture's API: list
the literal forms covered (empty and numeric vectors like "[]", "[1]", "[1, 2]",
trailing-comma variants like "[1,]" and "[1, 2,]", element expressions like "[x,
y + 1]"; and map literals "{}", "{a: 1}", "{a: 1,}", "{x: y, z: w}"), state that
it returns Vec<ExpressionCase> for use in parser tests, and give a short example
or note on how tests should consume the function (e.g., call to populate
parameterized test cases). Ensure the comment is a /// Rustdoc placed
immediately above collection_expression_cases so it appears in generated docs.
In `@src/parser/tests/expression/fixtures/valid/control_flow.rs`:
- Around line 13-17: Add a Rustdoc comment above the exported function
control_flow_expression_cases describing that it returns a Vec<ExpressionCase>
composed by first including all if_expression_cases() and then appending
match_and_for_expression_cases(), and note that ordering is significant
(if-cases first, then match/for cases). Mention the fixture groups included (if,
match, for) and the ordering behaviour so cargo doc will show the intent for
consumers.
In `@src/parser/tests/expression/fixtures/valid/structured.rs`:
- Around line 11-69: Add a Rustdoc comment above the pub(super) function
struct_and_closure_cases describing what syntax the fixture covers (struct
expressions, tuple structs/fields, closures, tuples, nested expressions) and the
return contract (returns Vec<ExpressionCase> of valid expression fixtures used
by tests). Mention any important semantics callers should know (e.g., each
ExpressionCase contains src and expected AST). Place the comment immediately
above the struct_and_closure_cases declaration so it appears in generated docs.
---
Duplicate comments:
In `@src/parser/tests/expression/fixtures/valid/postfix.rs`:
- Around line 117-123: Add a Rustdoc comment for the exported fixture entrypoint
function postfix_expression_cases to describe its purpose, scope and any
ordering guarantees for the returned cases; update the function signature area
(the pub(super) fn postfix_expression_cases() -> Vec<ExpressionCase>
declaration) to be preceded by a /// doc comment that briefly explains this
fixture, what categories it composes (field_and_method_call_cases,
call_and_slice_cases, diff_marker_cases, delay_cases), and that callers can rely
on the returned Vec ordering as defined by the appended extensions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a86368a6-ab3f-44bd-91f7-6303232343d5
📒 Files selected for processing (10)
src/parser/expression/pratt/delay.rssrc/parser/expression/pratt/diff.rssrc/parser/tests/expression/fixtures.rssrc/parser/tests/expression/fixtures/errors.rssrc/parser/tests/expression/fixtures/valid.rssrc/parser/tests/expression/fixtures/valid/basic.rssrc/parser/tests/expression/fixtures/valid/collections.rssrc/parser/tests/expression/fixtures/valid/control_flow.rssrc/parser/tests/expression/fixtures/valid/postfix.rssrc/parser/tests/expression/fixtures/valid/structured.rs
| #[cfg(test)] | ||
| mod tests { | ||
| use chumsky::error::SimpleReason; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Add a module doc comment to the tests module.
Start the test module with a //! comment describing its purpose and coverage focus.
As per coding guidelines: "Every Rust module must begin with a module level (//!) comment explaining the module's purpose and utility."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/parser/expression/pratt/delay.rs` around lines 54 - 56, Add a
module-level doc comment for the test module named `mod tests` in this file:
insert a `//!` comment immediately inside the `mod tests {` block that briefly
explains the module's purpose and what aspects of `delay` parsing it covers
(e.g., unit tests for Pratt parser delay expression handling, edge cases, and
expected error conditions) so the module complies with the guideline requiring a
module-level comment.
Summary
Changes
Core Refactor
Tests and Fixtures
Miscellaneous
How to test
Notes
◳ Generated by DevBoxer ◰
ℹ️ Tag @devboxerhub to ask questions and address PR feedback
📎 Task: https://www.devboxer.com/task/4e7f979f-30bc-45b5-844c-4e890802856c
📝 Closes #223
Summary by Sourcery
Refactor parser internals and tests into smaller, focused modules while preserving existing parsing behavior.
Enhancements:
Tests: