Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental/oneof combinator #31

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ascandone
Copy link
Contributor

No description provided.

Copy link

coderabbitai bot commented Jan 20, 2025

Warning

Rate limit exceeded

@ascandone has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 53 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between d134aad and b3352f3.

⛔ Files ignored due to path filters (1)
  • internal/parser/__snapshots__/parser_test.snap is excluded by !**/*.snap, !**/*.snap
📒 Files selected for processing (15)
  • Numscript.g4 (2 hunks)
  • internal/analysis/check.go (2 hunks)
  • internal/analysis/check_test.go (1 hunks)
  • internal/cmd/run.go (3 hunks)
  • internal/interpreter/batch_balances_query.go (1 hunks)
  • internal/interpreter/interpreter.go (8 hunks)
  • internal/interpreter/interpreter_test.go (1 hunks)
  • internal/parser/antlr/Numscript.interp (3 hunks)
  • internal/parser/antlr/numscript_base_listener.go (2 hunks)
  • internal/parser/antlr/numscript_listener.go (4 hunks)
  • internal/parser/antlr/numscript_parser.go (24 hunks)
  • internal/parser/ast.go (4 hunks)
  • internal/parser/parser.go (4 hunks)
  • internal/parser/parser_test.go (2 hunks)
  • numscript_test.go (1 hunks)

Walkthrough

The pull request introduces a new oneof construct to the Numscript language grammar, expanding the capabilities of source and destination definitions. This change involves modifications across multiple files in the parser, lexer, and interpreter components. The new feature allows grouping multiple sources and destinations under a single oneof keyword, enhancing the language's expressiveness for specifications in send statements. Additionally, the feature flag management system has been updated to accommodate this new construct, ensuring that the interpreter can handle it effectively.

Changes

File Change Summary
Numscript.g4 Added new grammar rules for oneof source and destination constructs
internal/interpreter/interpreter.go Updated feature flag management system to use a map for flags and added checks for ExperimentalOneofFeatureFlag
internal/parser/ast.go Added SourceOneof and DestinationOneof types to represent grouped sources and destinations
internal/parser/parser.go Added parsing support for oneof source and destination contexts
internal/parser/parser_test.go Added tests for oneof source and destination parsing
internal/parser/antlr/NumscriptLexer.interp Added new token literal name 'oneof' and symbolic name 'null'
internal/parser/antlr/NumscriptLexer.tokens Renumbered token definitions to accommodate new tokens
internal/parser/antlr/Numscript.interp Added token literal name 'oneof' and updated ATN entries
internal/parser/antlr/Numscript.tokens Complete renumbering of token identifiers
internal/parser/antlr/numscript_base_listener.go Added methods for entering and exiting srcOneof and destOneof
internal/parser/antlr/numscript_listener.go Added methods for handling srcOneof and destOneof in listener interface
internal/parser/antlr/numscript_parser.go Introduced new contexts for SrcOneof and DestOneof, and updated parsing logic
internal/interpreter/batch_balances_query.go Updated findBalancesQueries to handle SourceOneof
internal/interpreter/interpreter_test.go Added tests for various scenarios involving oneof
numscript_test.go Added test for send command utilizing oneof construct
internal/analysis/check.go Added case for handling SourceOneof in checkSource method
internal/cmd/run.go Introduced command-line flag for enabling oneof feature

Sequence Diagram

sequenceDiagram
    participant Parser
    participant AST
    participant Interpreter

    Parser->>Parser: Encounter 'oneof' source
    Parser->>AST: Create SourceOneof
    AST-->>Parser: Return grouped sources
    Parser->>Interpreter: Pass parsed sources
    Interpreter->>Interpreter: Process sources
Loading

Poem

🐰 Hop, hop, through the code we go,
A new oneof source starts to grow
Grouping sources with rabbit-like glee
Parsing magic, as simple as can be!
Numscript evolves, one bunny leap at a time 🌈


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Jan 20, 2025

Codecov Report

Attention: Patch coverage is 81.62602% with 113 lines in your changes missing coverage. Please review.

Project coverage is 63.25%. Comparing base (ae202e9) to head (b3352f3).

Files with missing lines Patch % Lines
internal/parser/antlr/numscript_parser.go 74.85% 76 Missing and 12 partials ⚠️
internal/analysis/check.go 40.00% 6 Missing ⚠️
internal/interpreter/interpreter.go 88.88% 4 Missing and 2 partials ⚠️
internal/cmd/run.go 0.00% 4 Missing ⚠️
internal/parser/antlr/numscript_base_listener.go 0.00% 4 Missing ⚠️
internal/interpreter/batch_balances_query.go 57.14% 2 Missing and 1 partial ⚠️
internal/parser/ast.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #31      +/-   ##
==========================================
- Coverage   63.27%   63.25%   -0.03%     
==========================================
  Files          29       29              
  Lines        6462     6766     +304     
==========================================
+ Hits         4089     4280     +191     
- Misses       2191     2289      +98     
- Partials      182      197      +15     

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

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: 1

🧹 Nitpick comments (5)
internal/interpreter/interpreter.go (1)

984-991: Use pointer receiver for checkFeatureFlag method

For consistency with other methods on programState and to avoid unnecessary copying of the struct, consider changing the receiver of the checkFeatureFlag method to a pointer receiver *programState.

Apply this diff:

-func (s programState) checkFeatureFlag(flag string) InterpreterError {
+func (s *programState) checkFeatureFlag(flag string) InterpreterError {
Numscript.g4 (1)

87-87: LGTM! Consider adding documentation.

The new oneof source rule is well-structured and follows the grammar's conventions. Consider adding a comment to document the purpose and behavior of this new construct.

Add a comment above the rule to explain its purpose:

+// oneof allows grouping multiple sources, where any one of them can be used as the source
 | 'oneof' LBRACE source* RBRACE		# srcOneof
internal/parser/parser_test.go (1)

84-91: Enhance test coverage with additional test cases.

While the basic test case is good, consider adding tests for:

  1. Empty oneof block
  2. Nested oneof blocks
  3. Error cases (e.g., invalid source within oneof)

Example test cases:

func TestOneofSourceEdgeCases(t *testing.T) {
    tests := []struct {
        name     string
        script   string
        wantErrs bool
    }{
        {
            name:     "empty oneof block",
            script:   `send $amt ( source = oneof { } destination = @d )`,
            wantErrs: true,
        },
        {
            name:     "nested oneof blocks",
            script:   `send $amt ( source = oneof { @s1 oneof { @s2 @s3 } } destination = @d )`,
            wantErrs: false,
        },
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            p := parser.Parse(tt.script)
            if tt.wantErrs {
                assert.NotEmpty(t, p.Errors)
            } else {
                assert.Empty(t, p.Errors)
                snaps.MatchSnapshot(t, p.Value)
            }
        })
    }
}
internal/parser/parser.go (1)

173-182: Consider adding validation for empty sources.

The implementation looks good and follows the pattern used for SrcInorderContext. However, consider adding validation to ensure that at least one source is provided in the oneof block, as an empty oneof block might not be semantically valid.

Consider this enhancement:

 case *parser.SrcOneofContext:
     var sources []Source
     for _, sourceCtx := range sourceCtx.AllSource() {
         sources = append(sources, parseSource(sourceCtx))
     }
+    if len(sources) == 0 {
+        // Add to ErrorListener or handle empty oneof block
+        listener.Errors = append(listener.Errors, ParserError{
+            Range: range_,
+            Msg:   "oneof block must contain at least one source",
+        })
+    }
     return &SourceOneof{
         Range:   range_,
         Sources: sources,
     }
internal/parser/antlr/numscript_lexer.go (1)

Line range hint 1-1: Reminder: This is an auto-generated file.

Changes to this file should be made through the Numscript.g4 grammar file, as any manual edits here will be overwritten when the lexer is regenerated.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae202e9 and 7b3503a.

⛔ Files ignored due to path filters (1)
  • internal/parser/__snapshots__/parser_test.snap is excluded by !**/*.snap, !**/*.snap
📒 Files selected for processing (13)
  • Numscript.g4 (1 hunks)
  • internal/interpreter/interpreter.go (4 hunks)
  • internal/parser/antlr/Numscript.interp (3 hunks)
  • internal/parser/antlr/Numscript.tokens (1 hunks)
  • internal/parser/antlr/NumscriptLexer.interp (4 hunks)
  • internal/parser/antlr/NumscriptLexer.tokens (1 hunks)
  • internal/parser/antlr/numscript_base_listener.go (1 hunks)
  • internal/parser/antlr/numscript_lexer.go (2 hunks)
  • internal/parser/antlr/numscript_listener.go (2 hunks)
  • internal/parser/antlr/numscript_parser.go (23 hunks)
  • internal/parser/ast.go (2 hunks)
  • internal/parser/parser.go (1 hunks)
  • internal/parser/parser_test.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • internal/parser/antlr/Numscript.tokens
🧰 Additional context used
🪛 GitHub Check: codecov/patch
internal/parser/antlr/numscript_base_listener.go

[warning] 185-185: internal/parser/antlr/numscript_base_listener.go#L185
Added line #L185 was not covered by tests


[warning] 188-188: internal/parser/antlr/numscript_base_listener.go#L188
Added line #L188 was not covered by tests

internal/parser/ast.go

[warning] 90-90: internal/parser/ast.go#L90
Added line #L90 was not covered by tests

internal/parser/antlr/numscript_parser.go

[warning] 2786-2787: internal/parser/antlr/numscript_parser.go#L2786-L2787
Added lines #L2786 - L2787 were not covered by tests


[warning] 2790-2791: internal/parser/antlr/numscript_parser.go#L2790-L2791
Added lines #L2790 - L2791 were not covered by tests


[warning] 2794-2795: internal/parser/antlr/numscript_parser.go#L2794-L2795
Added lines #L2794 - L2795 were not covered by tests


[warning] 2819-2826: internal/parser/antlr/numscript_parser.go#L2819-L2826
Added lines #L2819 - L2826 were not covered by tests


[warning] 2828-2828: internal/parser/antlr/numscript_parser.go#L2828
Added line #L2828 was not covered by tests


[warning] 2832-2834: internal/parser/antlr/numscript_parser.go#L2832-L2834
Added lines #L2832 - L2834 were not covered by tests


[warning] 2836-2836: internal/parser/antlr/numscript_parser.go#L2836
Added line #L2836 was not covered by tests


[warning] 2839-2842: internal/parser/antlr/numscript_parser.go#L2839-L2842
Added lines #L2839 - L2842 were not covered by tests


[warning] 2845-2848: internal/parser/antlr/numscript_parser.go#L2845-L2848
Added lines #L2845 - L2848 were not covered by tests


[warning] 3393-3394: internal/parser/antlr/numscript_parser.go#L3393-L3394
Added lines #L3393 - L3394 were not covered by tests


[warning] 3400-3400: internal/parser/antlr/numscript_parser.go#L3400
Added line #L3400 was not covered by tests


[warning] 3413-3413: internal/parser/antlr/numscript_parser.go#L3413
Added line #L3413 was not covered by tests


[warning] 3421-3422: internal/parser/antlr/numscript_parser.go#L3421-L3422
Added lines #L3421 - L3422 were not covered by tests


[warning] 3433-3434: internal/parser/antlr/numscript_parser.go#L3433-L3434
Added lines #L3433 - L3434 were not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (13)
internal/parser/ast.go (2)

106-109: LGTM!

The SourceOneof type is well-structured and consistent with other source types in the codebase.


90-90: Add test coverage for the source() method.

The source() method for SourceOneof is not covered by tests.

Run the following script to verify test coverage:

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 90-90: internal/parser/ast.go#L90
Added line #L90 was not covered by tests

internal/parser/antlr/Numscript.interp (1)

4-4: Skip review of auto-generated file.

This file is auto-generated by ANTLR and doesn't require manual review.

Also applies to: 45-45, 106-106

internal/parser/antlr/numscript_listener.go (1)

89-91: LGTM! The new listener methods are well-integrated.

The added EnterSrcOneof and ExitSrcOneof methods follow the established pattern and are properly documented.

Also applies to: 212-214

internal/parser/antlr/NumscriptLexer.interp (1)

4-4: LGTM! The lexer changes are consistent.

The new token literal 'oneof' and associated rules are properly integrated into the lexer's token definitions.

Also applies to: 45-45, 85-85, 131-131

internal/parser/antlr/numscript_base_listener.go (1)

184-189: LGTM! Base listener implementation follows the pattern.

The empty implementations for EnterSrcOneof and ExitSrcOneof are correct. The static analysis warning about test coverage can be safely ignored as this is generated code with intentionally empty implementations.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 185-185: internal/parser/antlr/numscript_base_listener.go#L185
Added line #L185 was not covered by tests


[warning] 188-188: internal/parser/antlr/numscript_base_listener.go#L188
Added line #L188 was not covered by tests

internal/parser/antlr/numscript_lexer.go (5)

46-49: LGTM! Token literal definitions are correct.

The addition of the 'oneof' token and the subsequent reindexing of token literals are consistent with the PR objective.


52-53: LGTM! Token symbolic names are properly aligned.

The symbolic names array is correctly updated to maintain consistency with the literal names and token constants.


60-65: LGTM! Token rule names are properly defined.

The rule names array is correctly updated to include the new 'oneof' token while maintaining proper indexing.


Line range hint 19-19: Address the TODO comment about EOF string.

The TODO comment suggests that the EOF string definition is missing. Consider implementing this to ensure complete lexer functionality.

Would you like me to help implement the EOF string definition?


267-303: LGTM! Token constants are correctly updated.

The token constants are properly incremented to accommodate the new 'oneof' token while maintaining consistency with the literal and symbolic names.

internal/parser/antlr/NumscriptLexer.tokens (2)

1-38: LGTM! Token ID assignments are properly sequenced.

The token renumbering maintains consistent sequential ordering while accommodating the new 'oneof' token.


40-64: Verify token ID consistency across parser components.

The literal mappings correctly reflect the updated token IDs. However, we should verify that these changes are consistently applied across related parser files.

✅ Verification successful

Token IDs are consistently defined across parser components

The token mappings, including 'oneof' (T__1=2), are consistently defined across all parser files. No mismatches or outdated token IDs were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify token ID consistency across parser files

# Check for any mismatches in token IDs
echo "Checking token ID consistency..."
for file in $(fd -e interp -e java -e go -e tokens . internal/parser/antlr); do
  echo "=== $file ==="
  # Look for 'oneof' token definitions and their IDs
  rg -A 1 -B 1 "'oneof'|T__1" "$file"
done

# Verify no hardcoded old token IDs remain
echo "Checking for old token IDs..."
rg "T__0.*=.*2|WS.*=.*2|NEWLINE.*=.*3" internal/parser/antlr/

Length of output: 3448

internal/parser/antlr/numscript_parser.go Show resolved Hide resolved
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: 1

🧹 Nitpick comments (2)
internal/interpreter/interpreter_test.go (1)

3546-3668: Consider refactoring oneof tests into a table-driven format to reduce duplication.

Refactoring these similar test cases into a table-driven test can enhance maintainability and make it easier to add new scenarios in the future.

numscript_test.go (1)

100-135: LGTM! Consider adding more test cases.

The test implementation correctly verifies the basic functionality of the oneof construct. However, consider adding test cases for:

  • Error handling when the feature flag is not enabled
  • Empty oneof block
  • Nested oneof blocks
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b3503a and 3dc51d4.

📒 Files selected for processing (7)
  • Numscript.g4 (1 hunks)
  • internal/interpreter/batch_balances_query.go (1 hunks)
  • internal/interpreter/interpreter.go (7 hunks)
  • internal/interpreter/interpreter_test.go (1 hunks)
  • internal/parser/antlr/Numscript.interp (3 hunks)
  • internal/parser/antlr/numscript_parser.go (23 hunks)
  • numscript_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/parser/antlr/Numscript.interp
  • Numscript.g4
🔇 Additional comments (10)
internal/parser/antlr/numscript_parser.go (1)

2772-2850: Code changes correctly integrate SrcOneofContext for the oneof construct.

The implementation of SrcOneofContext appropriately handles the new oneof grammar rule, ensuring that the parser can correctly parse and interpret scripts using the oneof construct.

internal/interpreter/batch_balances_query.go (1)

131-139: Correctly handle SourceOneof by recursively invoking findBalancesQueries.

The addition of the parser.SourceOneof case effectively integrates the new oneof construct into the balance query process, ensuring that balances are correctly calculated for all sub-sources within the oneof.

internal/interpreter/interpreter_test.go (5)

3546-3570: Test TestOneofInSourceSendFirstBranch validates oneof when the first branch succeeds.

The test correctly verifies that the oneof construct selects the first successful source (@a) when it allows unbounded overdraft.


3572-3595: Test TestOneofInSource handles first branch failure and second branch success in oneof.

This test ensures that when the first source fails due to insufficient overdraft allowance, the oneof construct correctly falls back to the second source (@world).


3597-3618: Test TestOneofAllFailing verifies error handling when all oneof branches fail.

The test appropriately checks that a MissingFundsErr is returned when none of the sources in oneof can satisfy the transfer amount.


3620-3645: Test TestOneofInSendAll validates oneof behavior in a send all context.

The test confirms that only the first successful source (@s1) is used in the send all operation, as expected with the oneof construct.


3647-3668: Test TestOneofSingleton checks oneof with a single source for correct behavior.

This test ensures that oneof operates correctly even when only one source is provided, verifying successful execution when the source has sufficient balance.

internal/interpreter/interpreter.go (3)

182-185: LGTM! Clean feature flag declaration.

The feature flags are well-organized and follow a consistent naming convention.


580-609: LGTM! Well-implemented backtracking logic.

The implementation correctly:

  1. Tries each source in order
  2. Backtracks if a source doesn't provide the full amount
  3. Falls back to the last source if no previous source succeeds

1027-1034: LGTM! Clean feature flag check implementation.

The helper method is well-implemented with:

  1. Clear error handling
  2. Consistent return type
  3. Reusable design

Comment on lines +479 to +488
case *parser.SourceOneof:
err := s.checkFeatureFlag(ExperimentalOneofFeatureFlag)
if err != nil {
return nil, err
}

// we can safely access the first one because empty oneof is parsing err
first := source.Sources[0]
return s.sendAll(first)

Copy link

@coderabbitai coderabbitai bot Jan 20, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Inconsistent behavior in sendAll method.

The oneof implementation in sendAll only uses the first source without trying alternatives. This differs from the behavior in trySendingUpTo where it tries each source until one succeeds. Consider making the behavior consistent by:

  1. Either documenting that sendAll always uses the first source
  2. Or implementing the same backtracking logic as in trySendingUpTo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's not inconsistent: this is indeed a backtracking operator, but when calling this method none of the branch can fail, hence we just forward to the first source

Copy link

Choose a reason for hiding this comment

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

@ascandone Thank you for the clarification. That makes perfect sense - since sources can't fail in "send all" context, using the first source is sufficient.


✏️ Learnings added
Learnt from: ascandone
PR: formancehq/numscript#31
File: internal/interpreter/interpreter.go:479-488
Timestamp: 2025-01-20T23:01:48.647Z
Learning: In the `sendAll` method of the Numscript interpreter, the `oneof` operator only uses the first source because none of the branches can fail in a "send all" context. This differs from `trySendingUpTo` where backtracking is needed as sources can fail when trying to send a specific amount.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

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: 1

🧹 Nitpick comments (1)
internal/cmd/run.go (1)

208-208: Enhance CLI flag documentation and test coverage.

While the flag registration follows the established pattern, consider these improvements:

  1. Add test coverage for CLI flag parsing
  2. Enhance the help text to better explain what the "oneof combinator" does and its use cases

Example of more detailed help text:

-cmd.Flags().BoolVar(&oneOfFeatureFlag, interpreter.ExperimentalOneofFeatureFlag, false, "feature flag to enable the oneof combinator")
+cmd.Flags().BoolVar(&oneOfFeatureFlag, interpreter.ExperimentalOneofFeatureFlag, false, "feature flag to enable the oneof combinator, which allows grouping multiple sources under a single source definition")
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 208-208: internal/cmd/run.go#L208
Added line #L208 was not covered by tests

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3dc51d4 and 0a620fa.

📒 Files selected for processing (2)
  • internal/analysis/check.go (1 hunks)
  • internal/cmd/run.go (3 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
internal/cmd/run.go

[warning] 125-127: internal/cmd/run.go#L125-L127
Added lines #L125 - L127 were not covered by tests


[warning] 208-208: internal/cmd/run.go#L208
Added line #L208 was not covered by tests

internal/analysis/check.go

[warning] 465-468: internal/analysis/check.go#L465-L468
Added lines #L465 - L468 were not covered by tests

🔇 Additional comments (2)
internal/analysis/check.go (1)

465-469: Implementation looks good but needs test coverage.

The implementation correctly handles the new SourceOneof type by recursively checking each source, following the same pattern as SourceInorder. However, the code coverage report indicates that these lines are not covered by tests.

Let's verify the test coverage and existing test patterns:

Would you like me to help generate test cases for the SourceOneof implementation?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 465-468: internal/analysis/check.go#L465-L468
Added lines #L465 - L468 were not covered by tests

internal/cmd/run.go (1)

30-30: LGTM!

The feature flag declaration follows the established pattern and is appropriately placed with other flag declarations.

Comment on lines +125 to +127
if oneOfFeatureFlag {
featureFlags[interpreter.ExperimentalOneofFeatureFlag] = struct{}{}
}
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Add test coverage for the oneof feature flag in the cmd package

The feature flag is well integrated with the interpreter package and has thorough test coverage there. However, the cmd package lacks test coverage for:

  • Flag parsing and validation
  • Feature flag propagation to the interpreter
  • Integration tests with the flag enabled/disabled
🔗 Analysis chain

Add test coverage for the oneof feature flag.

The feature flag implementation looks correct but lacks test coverage. Please add test cases to verify:

  1. Program behavior when the flag is enabled
  2. Program behavior when the flag is disabled
  3. Integration with the interpreter package's feature flag handling

Let's verify the feature flag integration with the interpreter package:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the interpreter package properly handles the oneof feature flag

# Check if the interpreter package defines the feature flag constant
rg -l "ExperimentalOneofFeatureFlag.*=.*\"" internal/interpreter/

# Check if there are corresponding feature flag checks in the interpreter
rg "ExperimentalOneofFeatureFlag" internal/interpreter/ -A 3 -B 3

# Look for test files that might need additional coverage
fd ".*test\.go$" internal/cmd/

Length of output: 3485


Script:

#!/bin/bash
# Check for feature flag testing in cmd package
rg "oneOfFeatureFlag" internal/cmd/ -A 3 -B 3

# Look for any test files that might contain feature flag tests
rg "TestRun.*Flag" internal/cmd/ -A 3 -B 3

# Check for any feature flag related test helpers
rg "testRun.*Flag" internal/cmd/ -A 3 -B 3

Length of output: 1402

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 125-127: internal/cmd/run.go#L125-L127
Added lines #L125 - L127 were not covered by tests

@ascandone ascandone force-pushed the experimental/oneof-combinator branch 2 times, most recently from b9eba74 to 9f81e2c Compare January 20, 2025 23:30
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: 2

🧹 Nitpick comments (2)
internal/analysis/check_test.go (1)

200-223: LGTM! Consider adding edge cases.

The test effectively validates the basic unbound variable detection in oneof blocks.

Consider adding test cases for:

  • Multiple unbound variables in the same oneof block
  • Nested oneof blocks with unbound variables
  • Mixed bound and unbound variables in the same oneof block
internal/parser/ast.go (1)

163-165: Consider adding validation methods for destination types.

Both DestinationInorder and DestinationOneof share similar fields. Consider adding validation methods to ensure the Remaining field is properly set.

+func (d *DestinationInorder) Validate() error {
+    if d.Remaining == nil {
+        return errors.New("remaining clause is required")
+    }
+    return nil
+}
+
+func (d *DestinationOneof) Validate() error {
+    if d.Remaining == nil {
+        return errors.New("remaining clause is required")
+    }
+    return nil
+}

Also applies to: 167-171

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a620fa and d134aad.

⛔ Files ignored due to path filters (1)
  • internal/parser/__snapshots__/parser_test.snap is excluded by !**/*.snap, !**/*.snap
📒 Files selected for processing (11)
  • Numscript.g4 (2 hunks)
  • internal/analysis/check.go (1 hunks)
  • internal/analysis/check_test.go (1 hunks)
  • internal/cmd/run.go (3 hunks)
  • internal/parser/antlr/Numscript.interp (3 hunks)
  • internal/parser/antlr/numscript_base_listener.go (2 hunks)
  • internal/parser/antlr/numscript_listener.go (4 hunks)
  • internal/parser/antlr/numscript_parser.go (24 hunks)
  • internal/parser/ast.go (4 hunks)
  • internal/parser/parser.go (4 hunks)
  • internal/parser/parser_test.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/cmd/run.go
  • internal/analysis/check.go
  • internal/parser/antlr/numscript_listener.go
  • internal/parser/antlr/numscript_base_listener.go
🔇 Additional comments (8)
Numscript.g4 (2)

87-87: LGTM! Source oneof grammar is well-defined.

The grammar for source oneof is clear and consistent with existing patterns.


97-100: Verify the requirement for REMAINING in destination oneof.

The grammar enforces that destination oneof must have a REMAINING clause. This seems to differ from the regular destination rule which makes it optional.

internal/parser/ast.go (1)

106-109: LGTM! SourceOneof type is well-structured.

The type definition follows the established pattern and correctly implements the Source interface.

internal/parser/antlr/Numscript.interp (1)

4-4: LGTM! Parser configuration updated correctly for the new oneof construct.

The changes properly integrate the new oneof token into the parser's configuration, with appropriate updates to token indices and ATN entries.

Also applies to: 106-106

internal/parser/parser.go (3)

173-181: LGTM! Source parsing correctly handles the new oneof construct.

The implementation follows the same pattern as other source types, properly collecting all sources from the context.


Line range hint 401-422: LGTM! Destination parsing updated to support oneof construct.

The changes correctly handle the new destination type while maintaining consistency with existing patterns.


448-449: LGTM! Return type updated for destination clause parsing.

The change from DestinationInorderClause to CappedKeptOrDestination aligns with the new grammar structure.

internal/parser/antlr/numscript_parser.go (1)

2778-2856: LGTM! Auto-generated parser code.

This is auto-generated code from ANTLR and correctly implements the parser rules for the new oneof construct.

Also applies to: 4103-4200

Comment on lines +84 to +91
func TestOneofSource(t *testing.T) {
p := parser.Parse(`send $amt (
source = oneof { @s1 @s2 }
destination = @d
)`)
require.Empty(t, p.Errors)
snaps.MatchSnapshot(t, p.Value)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error cases for oneof source parsing.

The test covers the happy path but lacks error cases.

Consider adding tests for:

  • Empty oneof block
  • Invalid syntax within oneof
  • Nested oneof blocks

Comment on lines +115 to +126
func TestOneofDestination(t *testing.T) {
p := parser.Parse(`send $amt (
source = @s
destination = oneof {
max $m1 to @d1
max $m2 kept
remaining to @d3
}
)`)
require.Empty(t, p.Errors)
snaps.MatchSnapshot(t, p.Value)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add edge cases for oneof destination parsing.

While the basic functionality is tested, edge cases should be covered.

Consider adding tests for:

  • Missing REMAINING clause
  • Multiple REMAINING clauses
  • Invalid max expressions

@ascandone ascandone force-pushed the experimental/oneof-combinator branch from 7e6572b to b3352f3 Compare January 20, 2025 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant