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

Implemented string_to_account() function expression #28

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ascandone
Copy link
Contributor

This function implements two distinct functionalities:

  1. overloading the "+" operator with strings concatenation
    1. e.g. allowing "ab" + "cd" (=> "abcd")
  2. create a string_to_account function which can be used to cast strings into account

Feature flags

feature 2) is under the --experimental-string-to-account-function feature flag.
The string concatenation feature IS NOT under a feature flag. This means merging this PR will be equivalent as considering this functionality stable (in the numscript rewrite). This is discussed in the next paragraph

Design consideration for string concatenation

It's safe to assume current design of string concatenation is good enough to be merged, e.g. we won't need any breaking changes.
While operator overloading's cost is to prevent a fully fledged type inference,

  1. we already have operator overload for monetary+monetary and number+number operations
  2. type inference is not needed as long as we have mandatory type annotations (e.g. in the "vars" block), and it's a good idea to maintain them mandatory for the sake of explicitness, and in order to allow the runtime not to depend on the static analysis (so that there isn't any perf overhead)
    Other further development of the functionality will need more considerations, e.g. either forbidding "ab" + 2 (current behaviour) or casting 2 to a string. The latter is, however, not a breaking change

Open ended questions

  1. should the function make sure numscript's grammar for account names is respected?

Copy link

coderabbitai bot commented Dec 6, 2024

Walkthrough

The changes introduce new functionalities for handling account-related operations in the interpreter module. A constant for converting strings to accounts is added, along with new functions for managing metadata and evaluating expressions involving strings. The ability to concatenate strings and convert them to account representations is enhanced, while several older functions related to balance and metadata retrieval are removed. Additionally, corresponding test cases are introduced to validate these new features and ensure proper functionality.

Changes

File Change Summary
internal/analysis/check.go Added constant FnVarOriginStringToAccount and entry in Builtins map for string-to-account conversion functionality.
internal/interpreter/evaluate_expr.go Updated evaluateExpr to handle parser.StringLiteral and modified plusOp to support string concatenation.
internal/interpreter/function_expressions.go Introduced functions: stringToAccount, meta, balance, overdraft, and getBalance for account management.
internal/interpreter/function_statements.go Added functions: setTxMeta and setAccountMeta for managing transaction and account metadata.
internal/interpreter/infix.go Implemented evalAdd for String type to support string concatenation in addition operations.
internal/interpreter/interpreter.go Added stringToAccount handling in handleOrigin, introduced feature flag for string-to-account conversion, and removed several functions related to balances and metadata.
internal/interpreter/interpreter_test.go Added tests: TestPlusStringOverload for string concatenation and TestToAccount for string-to-account conversion.

Possibly related PRs

Suggested reviewers

  • altitude
  • gfyrag

Poem

In the burrow where rabbits play,
New features hop in bright array.
Strings to accounts, a leap so grand,
With metadata close at hand.
Let's celebrate with joy and cheer,
For changes made, we hold so dear! 🐇✨


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 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 Dec 6, 2024

Codecov Report

Attention: Patch coverage is 78.10219% with 30 lines in your changes missing coverage. Please review.

Project coverage is 63.29%. Comparing base (9bf4d35) to head (be83e34).

Files with missing lines Patch % Lines
internal/interpreter/function_expressions.go 75.25% 16 Missing and 8 partials ⚠️
internal/interpreter/function_statements.go 88.00% 2 Missing and 1 partial ⚠️
internal/interpreter/infix.go 57.14% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #28      +/-   ##
==========================================
+ Coverage   63.24%   63.29%   +0.05%     
==========================================
  Files          29       31       +2     
  Lines        6456     6482      +26     
==========================================
+ Hits         4083     4103      +20     
- Misses       2191     2195       +4     
- Partials      182      184       +2     

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

@ascandone ascandone marked this pull request as draft December 6, 2024 17:40
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

🧹 Outside diff range and nitpick comments (7)
internal/interpreter/function_expressions.go (4)

18-18: Reminder: Implement precise error location handling

The TODO comment on line 18 (// TODO more precise location) indicates that the error ranges in the stringToAccount function could be made more precise. Enhancing error location precision can significantly improve debugging and user feedback.


34-34: Reminder: Implement precise error location handling

The TODO comment on line 34 suggests improving the precision of error ranges in the meta function. Providing exact locations for errors can aid in quicker diagnosis and resolution.


67-67: Reminder: Implement precise error location handling

In the balance function, the TODO comment on line 67 (// TODO more precise args range location) highlights the need for precise argument range handling. Consider refining this to enhance error reporting.


108-108: Reminder: Implement precise error location handling

The TODO on line 108 in the overdraft function indicates that argument range precision needs attention. Addressing this will improve the clarity of error messages.

internal/interpreter/infix.go (1)

28-35: Handle non-string operands in string concatenation

The evalAdd method for the String type enables string concatenation. While the current implementation assumes that the right operand is a string, consider adding explicit error messages or type checks for cases where the operand is not a string to improve robustness.

internal/analysis/check.go (1)

85-89: Consider enhancing the function documentation.

While the current documentation is clear, it would be helpful to add more details about:

  • Expected string format for valid account names
  • Behavior with empty strings or invalid characters
  • Any length restrictions
 FnVarOriginStringToAccount: VarOriginFnCallResolution{
   Params: []string{TypeString},
   Return: TypeAccount,
-  Docs:   "cast a string to an account",
+  Docs:   "cast a string to an account. The string must be a valid account name following numscript's grammar rules. Empty strings and invalid characters will result in an error.",
 },
internal/interpreter/interpreter_test.go (1)

3547-3562: Add more test cases for string concatenation.

While the basic test is good, consider adding test cases for:

  • Empty strings: "" + "abc", "abc" + "", "" + ""
  • Long strings to verify any length limitations
  • Special characters and Unicode strings
  • Multiple concatenations: "a" + "b" + "c"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9bf4d35 and be83e34.

📒 Files selected for processing (7)
  • internal/analysis/check.go (2 hunks)
  • internal/interpreter/evaluate_expr.go (1 hunks)
  • internal/interpreter/function_expressions.go (1 hunks)
  • internal/interpreter/function_statements.go (1 hunks)
  • internal/interpreter/infix.go (2 hunks)
  • internal/interpreter/interpreter.go (4 hunks)
  • internal/interpreter/interpreter_test.go (2 hunks)
🔇 Additional comments (8)
internal/interpreter/function_expressions.go (1)

143-151: Verify error handling in getBalance function

Ensure that the error wrapping and handling in the getBalance function provide sufficient context. When s.runBalancesQuery() returns an error, confirming that QueryBalanceError includes all necessary information will aid in debugging.

internal/interpreter/interpreter.go (4)

150-152: Integration of stringToAccount function in handleOrigin

The addition of the case for analysis.FnVarOriginStringToAccount correctly integrates the new stringToAccount function into the handleOrigin method. This allows the interpreter to handle string-to-account conversions as intended.


185-188: Consistency in feature flag declarations

The feature flag ExperimentalStringToAccountFunctionFeatureFlag is consistently declared alongside ExperimentalOverdraftFunctionFeatureFlag. This naming convention maintains clarity and aligns with existing feature flags.


213-216: Feature flag activation for StringToAccountFunction

The code correctly checks for the ExperimentalStringToAccountFunctionFeatureFlag and activates the corresponding feature in the RunProgram function. This ensures the experimental feature is only enabled when intended.


274-275: Addition of StringToAccountFunctionFeatureFlag to programState

The new boolean field StringToAccountFunctionFeatureFlag is added to the programState struct. Verify that this addition does not introduce unintended side effects, especially regarding struct initialization and memory alignment.

internal/interpreter/function_statements.go (1)

32-32: Confirm correct string conversion of metadata values

On line 32, the meta value is converted to a string using (*meta).String(). Ensure that all meta values can be accurately represented as strings and that this conversion does not lose important information, especially if meta values might be of non-string types.

internal/interpreter/evaluate_expr.go (1)

103-105: Extension of plusOp to support string concatenation

By mapping expectString in the plusOp function, the code now supports string concatenation using the "+" operator. This extension aligns with the overloaded operator functionality. Ensure that this addition does not conflict with other type operations and that adequate test coverage is in place.

internal/analysis/check.go (1)

59-59: LGTM! The constant declaration follows the established pattern.

The constant name and value are consistent with other function declarations in the codebase.

return err
}

st.TxMeta[*key] = *meta
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure thread safety when modifying TxMeta

In the setTxMeta function, assigning to st.TxMeta[*key] occurs without synchronization. If programState may be accessed concurrently, consider implementing mutex locks or other synchronization mechanisms to prevent potential data races.

Comment on lines +3564 to +3590
func TestToAccount(t *testing.T) {
script := `
vars {
account $acc = string_to_account("account_name")
}

send [COIN 10] (
source = @world
destination = $acc
)
`

tc := NewTestCase()
tc.compile(t, script)

tc.expected = CaseResult{
Postings: []Posting{
{
Source: "world",
Destination: "account_name",
Amount: big.NewInt(10),
Asset: "COIN",
},
},
}
testWithFeatureFlag(t, tc, machine.ExperimentalStringToAccountFunctionFeatureFlag)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance test coverage for string_to_account function.

The current test only covers the happy path. Consider adding test cases for:

  1. Invalid account names
  2. Empty strings
  3. Special characters
  4. Very long strings
  5. Account names with spaces or invalid characters

Also, consider extracting the feature flag constant to avoid magic strings:

+const experimentalStringToAccountTestFlag = machine.ExperimentalStringToAccountFunctionFeatureFlag

 func TestToAccount(t *testing.T) {
     // ... test code ...
-    testWithFeatureFlag(t, tc, machine.ExperimentalStringToAccountFunctionFeatureFlag)
+    testWithFeatureFlag(t, tc, experimentalStringToAccountTestFlag)
 }

+func TestToAccountErrors(t *testing.T) {
+    testCases := []struct {
+        name          string
+        accountName   string
+        expectedError machine.InterpreterError
+    }{
+        {"empty_string", "", machine.InvalidAccountName{Name: ""}},
+        {"invalid_chars", "account@name", machine.InvalidAccountName{Name: "account@name"}},
+        // Add more test cases
+    }
+    // ... implement test cases
+}

Committable suggestion skipped: line range outside the PR's diff.

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