Skip to content

Fix lint violations in stdlib/test/ and stdlib/bootstrap-test/ (BT-964)#1005

Merged
jamesc merged 2 commits intomainfrom
worktree-BT-964
Feb 28, 2026
Merged

Fix lint violations in stdlib/test/ and stdlib/bootstrap-test/ (BT-964)#1005
jamesc merged 2 commits intomainfrom
worktree-BT-964

Conversation

@jamesc
Copy link
Owner

@jamesc jamesc commented Feb 28, 2026

Summary

  • Removes 1974 unnecessary trailing . statement separators
  • Removes 662 unnecessary parentheses
  • Removes ~47 trailing ^ on last expressions (use ^ only for early returns)
  • Converts 5 non-self cascade candidates (arr/bus/c receivers) to cascade syntax
  • Fixes multi_expr_calc.bt fixture: replaces effect-free non-last expressions with unary sends

Lint changes

Two targeted lint improvements to eliminate false positives:

  1. effect_free_statement: Skip module-level expression sequences. Bootstrap-test files use module-level expressions as test assertions (paired with // => comments) — these are intentionally evaluated and should not be flagged.

  2. cascade_candidate: Exempt self from cascade checking. Consecutive sends to self (e.g. BUnit's self assert:…; assert:…) would be harder to debug as a cascade — independent test assertions should remain as separate statements so failures can be isolated.

Test plan

  • beamtalk lint stdlib/test/ → 0 violations
  • beamtalk lint stdlib/bootstrap-test/ → 0 violations
  • just test-stdlib → 237 tests passed, 645 BUnit tests passed
  • just test → all unit tests passed
  • just clippy → passed

https://linear.app/beamtalk/issue/BT-964

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Cascade detection refined to avoid flagging module-level sequences and to ignore chains sent to self, reducing false positives and preserving common self-assertion patterns.
    • Effect-free statement checks updated to skip top-level/module expressions.
  • Style

    • Vast test-suite formatting normalization: removed trailing periods/unnecessary parentheses and simplified return forms for consistent, indentation-friendly tests.

… BT-964

- Remove 1974 unnecessary trailing `.` statement separators
- Remove 662 unnecessary parentheses
- Remove ~47 trailing `^` on last expressions (implicit returns)
- Fix 5 non-self cascade candidates (arr/bus/c receivers)
- Fix multi_expr_calc.bt fixture: replace effect-free non-last expressions
- Lint: skip module-level expressions in effect_free_statement check
  (bootstrap-test files use module-level expressions as test assertions)
- Lint: exempt `self` from cascade_candidate — consecutive sends to self
  (e.g. BUnit assertions) should remain as separate statements for
  readability and debuggability

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9226b1b and da79b88.

📒 Files selected for processing (2)
  • stdlib/test/fixtures/error_counter.bt
  • stdlib/test/fixtures/nlr_baz.bt
🚧 Files skipped from review as they are similar to previous changes (2)
  • stdlib/test/fixtures/nlr_baz.bt
  • stdlib/test/fixtures/error_counter.bt

📝 Walkthrough

Walkthrough

Cascade and effect-free statement linters were changed to skip module-level/top-level expressions and to only inspect class (instance & class) and standalone method bodies; cascade checks now ignore runs of consecutive sends to self. Numerous tests and fixtures were reformatted (trailing-period/parentheses removal) and some fixtures switched from explicit ^ returns to implicit returns.

Changes

Cohort / File(s) Summary
Lint Logic
crates/beamtalk-core/src/lint/cascade_candidate.rs, crates/beamtalk-core/src/semantic_analysis/validators.rs
Restrict traversal to class methods and standalone method defs; skip module-level expressions; cascade check now treats 3+ consecutive sends to the same self receiver as non-flagged; removed use/import of for_each_expr_seq; added inline docs.
Return-expression normalization (fixtures)
stdlib/test/fixtures/... (e.g., abstract_shape.bt, counter.bt, error_counter.bt, field_mutation_*.bt, local_mutation_actor.bt, multi_keyword.bt, mutation_return_values.bt, nlr_baz.bt, self_ref_actor.bt, untyped_container.bt, value_type_builder.bt)
Converted explicit returns (^expr) to implicit last-expression returns in many getters/methods; small body punctuation cleanup.
Test assertion & syntax normalization
stdlib/test/... (~120 files, examples: actor_*, array_test.bt, collections_test.bt, stream_*, string_*, etc.)
Systematic formatting-only edits: removed trailing periods, simplified parentheses around receivers/expressions, converted multi-line statements to chained forms in places. No semantic changes to assertions.
Bootstrap tests & minor test comment fixes
stdlib/bootstrap-test/arithmetic.bt, stdlib/bootstrap-test/array_ops.bt, stdlib/bootstrap-test/equality.bt, stdlib/bootstrap-test/erlang_exceptions.bt, stdlib/bootstrap-test/errors.bt, stdlib/bootstrap-test/exceptions.bt, stdlib/bootstrap-test/symbol.bt
Small syntax/comment tweaks (e.g., change -0 - (-5)0 - -5, punctuation cleanup). No behavior changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant LintRunner as Lint Runner
  participant Pass as CascadeCandidatePass
  participant AST as AST (Module/Class/Method)
  participant Checker as CascadeChecker

  LintRunner->>Pass: invoke check on module
  Pass->>AST: iterate classes & standalone method defs
  AST-->>Pass: method bodies (only)
  Pass->>Checker: run check_sequence on each method body
  alt run is 3+ sends to same receiver & receiver == self
    Checker-->>Pass: skip (no lint)
  else other potential cascade
    Checker-->>Pass: emit lint finding
  end
  Pass-->>LintRunner: aggregated findings
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main changes: fixing lint violations in test directories related to BT-964.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch worktree-BT-964

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

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)
stdlib/test/fixtures/actor_collect_counter.bt (1)

15-16: Consider extracting a shared counter-increment helper.

self.count := self.count + 1 is repeated across multiple methods/blocks. A tiny helper would reduce duplication and keep fixture intent clearer.

Also applies to: 33-34, 48-54

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@stdlib/test/fixtures/actor_collect_counter.bt` around lines 15 - 16, Extract
the repeated increment logic into a small helper (e.g., increment_count or
incSelfCount) that updates self.count (performing self.count := self.count + 1)
and return/produce any needed value if callers expect it; then replace each
direct occurrence of self.count := self.count + 1 (including the instance
followed by item * 2 and other repeats) with calls to that helper to remove
duplication and clarify intent, updating callers to use the helper's return
value or side effect as appropriate.
crates/beamtalk-core/src/lint/cascade_candidate.rs (1)

229-379: Add a regression test for skipped module-level sequences.

Given the new scope behavior, a direct test for top-level arr add: runs would lock this contract and prevent accidental reintroduction.

💡 Suggested test addition
@@
     #[test]
+    fn module_level_sequence_not_flagged() {
+        let diags = lint("arr add: 1\narr add: 2\narr add: 3\n");
+        assert!(
+            diags.is_empty(),
+            "module-level sequences should be skipped, got: {diags:?}"
+        );
+    }
+
+    #[test]
     fn class_method_body_flagged() {
         let diags = lint(
             "Object subclass: Foo\n  class\n  setup: arr =>\n    arr add: 1\n    arr add: 2\n    arr add: 3\n",
         );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/beamtalk-core/src/lint/cascade_candidate.rs` around lines 229 - 379,
Add a new unit test in cascade_candidate.rs that ensures top-level
(module-level) consecutive sends are checked: create a #[test] (e.g.
module_level_sequences_flagged) which calls the existing lint(...) helper with a
snippet containing three consecutive top-level "arr add: X" sends (no enclosing
class/method), assert that lint returns one diagnostic (Severity::Lint) and that
the message mentions "cascade" (and optionally the run length). This locks the
regression for skipped module-level sequences.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@stdlib/test/fixtures/error_counter.bt`:
- Around line 1-2: Add the required license header to the top of this .bt source
file: insert a two-line header containing "Copyright 2026 James Casey" and
"SPDX-License-Identifier: Apache-2.0" before any existing content (e.g., before
the actor comment used by the tests/stdlib/exception_mutations.bt fixture) so
the file begins with the required license lines.

In `@stdlib/test/fixtures/nlr_baz.bt`:
- Around line 4-6: Update the stale fixture comments in NlrBaz to reflect the
current implementation: remove or reword the sentence "Do not simplify to `x +
x`" since the fixture now contains `x + x`, clarify that the test ensures
top-level ^ still works after NLR changes, and add the coding-guideline note
that ^ must be used only for early returns (not on the final expression) to
match the new return-style policy; ensure the comment references the top-level ^
and the `x + x` expression so readers can reconcile intent and code.

---

Nitpick comments:
In `@crates/beamtalk-core/src/lint/cascade_candidate.rs`:
- Around line 229-379: Add a new unit test in cascade_candidate.rs that ensures
top-level (module-level) consecutive sends are checked: create a #[test] (e.g.
module_level_sequences_flagged) which calls the existing lint(...) helper with a
snippet containing three consecutive top-level "arr add: X" sends (no enclosing
class/method), assert that lint returns one diagnostic (Severity::Lint) and that
the message mentions "cascade" (and optionally the run length). This locks the
regression for skipped module-level sequences.

In `@stdlib/test/fixtures/actor_collect_counter.bt`:
- Around line 15-16: Extract the repeated increment logic into a small helper
(e.g., increment_count or incSelfCount) that updates self.count (performing
self.count := self.count + 1) and return/produce any needed value if callers
expect it; then replace each direct occurrence of self.count := self.count + 1
(including the instance followed by item * 2 and other repeats) with calls to
that helper to remove duplication and clarify intent, updating callers to use
the helper's return value or side effect as appropriate.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3421019 and 9226b1b.

📒 Files selected for processing (178)
  • crates/beamtalk-core/src/lint/cascade_candidate.rs
  • crates/beamtalk-core/src/semantic_analysis/validators.rs
  • stdlib/bootstrap-test/arithmetic.bt
  • stdlib/bootstrap-test/array_ops.bt
  • stdlib/bootstrap-test/equality.bt
  • stdlib/bootstrap-test/erlang_exceptions.bt
  • stdlib/bootstrap-test/errors.bt
  • stdlib/bootstrap-test/exceptions.bt
  • stdlib/bootstrap-test/symbol.bt
  • stdlib/test/abstract_classes_test.bt
  • stdlib/test/actor_class_local_var_test.bt
  • stdlib/test/actor_conditional_mutations_test.bt
  • stdlib/test/actor_coordination_test.bt
  • stdlib/test/actor_deadlock_test.bt
  • stdlib/test/actor_lifecycle_test.bt
  • stdlib/test/actor_local_mutations_test.bt
  • stdlib/test/actor_message_chaining_test.bt
  • stdlib/test/actor_non_local_return_test.bt
  • stdlib/test/actor_self_send_collect_test.bt
  • stdlib/test/actor_slot_test.bt
  • stdlib/test/architecture_doc_examples_test.bt
  • stdlib/test/arithmetic_operations_test.bt
  • stdlib/test/arithmetic_test.bt
  • stdlib/test/array_test.bt
  • stdlib/test/association_test.bt
  • stdlib/test/beamtalk_interface_test.bt
  • stdlib/test/block_evaluation_test.bt
  • stdlib/test/blocks_test.bt
  • stdlib/test/cast_send_test.bt
  • stdlib/test/character_test.bt
  • stdlib/test/class_builder_test.bt
  • stdlib/test/class_hierarchy_query_test.bt
  • stdlib/test/class_method_self_new_test.bt
  • stdlib/test/class_object_dispatch_test.bt
  • stdlib/test/class_reflection_test.bt
  • stdlib/test/class_self_dispatch_test.bt
  • stdlib/test/class_state_test.bt
  • stdlib/test/class_variables_singleton_test.bt
  • stdlib/test/class_variables_test.bt
  • stdlib/test/closures_advanced_test.bt
  • stdlib/test/codegen_doc_test.bt
  • stdlib/test/collection_mutations_test.bt
  • stdlib/test/collection_protocol_test.bt
  • stdlib/test/collections_test.bt
  • stdlib/test/compiled_method_test.bt
  • stdlib/test/counter_test.bt
  • stdlib/test/custom_collection_test.bt
  • stdlib/test/custom_exceptions_test.bt
  • stdlib/test/datetime_test.bt
  • stdlib/test/dictionary_test.bt
  • stdlib/test/display_string_test.bt
  • stdlib/test/doc_test_example.bt
  • stdlib/test/empty_method_self_test.bt
  • stdlib/test/erlang_interop_test.bt
  • stdlib/test/error_message_test.bt
  • stdlib/test/error_method_test.bt
  • stdlib/test/exception_mutations_test.bt
  • stdlib/test/field_mutations_do_test.bt
  • stdlib/test/file_io_test.bt
  • stdlib/test/file_stream_test.bt
  • stdlib/test/fixtures/abstract_shape.bt
  • stdlib/test/fixtures/actor_chaining_fixture.bt
  • stdlib/test/fixtures/actor_class_local_var.bt
  • stdlib/test/fixtures/actor_collect_counter.bt
  • stdlib/test/fixtures/actor_coordination_fixture.bt
  • stdlib/test/fixtures/actor_nlr_basic.bt
  • stdlib/test/fixtures/actor_nlr_computed.bt
  • stdlib/test/fixtures/actor_nlr_local_var.bt
  • stdlib/test/fixtures/actor_nlr_mutate.bt
  • stdlib/test/fixtures/actor_nlr_on_do.bt
  • stdlib/test/fixtures/actor_nlr_recursive.bt
  • stdlib/test/fixtures/actor_slot_fixture.bt
  • stdlib/test/fixtures/circle.bt
  • stdlib/test/fixtures/class_method_self_new.bt
  • stdlib/test/fixtures/class_state_actor.bt
  • stdlib/test/fixtures/conditional_mutation_counter.bt
  • stdlib/test/fixtures/counter.bt
  • stdlib/test/fixtures/deadlock_a.bt
  • stdlib/test/fixtures/deadlock_b.bt
  • stdlib/test/fixtures/error_counter.bt
  • stdlib/test/fixtures/error_message_helper.bt
  • stdlib/test/fixtures/event_bus_fixture.bt
  • stdlib/test/fixtures/field_mutation_accumulator.bt
  • stdlib/test/fixtures/field_mutation_counter.bt
  • stdlib/test/fixtures/field_mutation_nested.bt
  • stdlib/test/fixtures/hom_composability_actor.bt
  • stdlib/test/fixtures/local_mutation_actor.bt
  • stdlib/test/fixtures/logging_counter.bt
  • stdlib/test/fixtures/math_helper.bt
  • stdlib/test/fixtures/mixed_call_site_actor.bt
  • stdlib/test/fixtures/multi_expr_calc.bt
  • stdlib/test/fixtures/multi_keyword.bt
  • stdlib/test/fixtures/mutation_return_values.bt
  • stdlib/test/fixtures/nlr_bar.bt
  • stdlib/test/fixtures/nlr_baz.bt
  • stdlib/test/fixtures/nlr_doubler.bt
  • stdlib/test/fixtures/nlr_field_mutation.bt
  • stdlib/test/fixtures/nlr_foo.bt
  • stdlib/test/fixtures/nlr_nested_hom.bt
  • stdlib/test/fixtures/nlr_on_do.bt
  • stdlib/test/fixtures/nlr_return_test.bt
  • stdlib/test/fixtures/nlr_skipper.bt
  • stdlib/test/fixtures/non_literal_callable_actor.bt
  • stdlib/test/fixtures/number_list.bt
  • stdlib/test/fixtures/recursive_actor.bt
  • stdlib/test/fixtures/removal_test_child.bt
  • stdlib/test/fixtures/removal_test_parent.bt
  • stdlib/test/fixtures/sealed_counter.bt
  • stdlib/test/fixtures/self_ref_actor.bt
  • stdlib/test/fixtures/string_formatter.bt
  • stdlib/test/fixtures/tier2_block_test_actor.bt
  • stdlib/test/fixtures/typed_account.bt
  • stdlib/test/fixtures/typed_counter.bt
  • stdlib/test/fixtures/typed_ledger.bt
  • stdlib/test/fixtures/untyped_container.bt
  • stdlib/test/fixtures/value_point.bt
  • stdlib/test/fixtures/value_type_builder.bt
  • stdlib/test/future_auto_await_test.bt
  • stdlib/test/hom_composability_test.bt
  • stdlib/test/instance_class_var_access_test.bt
  • stdlib/test/instance_class_var_access_value_type_test.bt
  • stdlib/test/integer_bitwise_test.bt
  • stdlib/test/json_test.bt
  • stdlib/test/keyword_messages_test.bt
  • stdlib/test/language_features_doc_test.bt
  • stdlib/test/list_literals_test.bt
  • stdlib/test/math_test.bt
  • stdlib/test/metaclass_test.bt
  • stdlib/test/method_resolver_hierarchy_test.bt
  • stdlib/test/mixed_call_site_test.bt
  • stdlib/test/mutation_return_values_test.bt
  • stdlib/test/nested_to_do_test.bt
  • stdlib/test/nil_protocol_test.bt
  • stdlib/test/nlr_state_threading_test.bt
  • stdlib/test/non_literal_callable_test.bt
  • stdlib/test/number_methods_test.bt
  • stdlib/test/object_protocol_test.bt
  • stdlib/test/pattern_matching_test.bt
  • stdlib/test/protoobject_actors_test.bt
  • stdlib/test/protoobject_manual_test.bt
  • stdlib/test/random_test.bt
  • stdlib/test/recursion_test.bt
  • stdlib/test/reflection_basic_test.bt
  • stdlib/test/regex_test.bt
  • stdlib/test/remove_from_system_test.bt
  • stdlib/test/runtime_doc_test.bt
  • stdlib/test/sealed_class_test.bt
  • stdlib/test/self_reference_test.bt
  • stdlib/test/semantic_scope_test.bt
  • stdlib/test/set_test.bt
  • stdlib/test/setup_state_test.bt
  • stdlib/test/source_file_reload_test.bt
  • stdlib/test/species_test.bt
  • stdlib/test/stack_frame_test.bt
  • stdlib/test/stream_collections_test.bt
  • stdlib/test/stream_test.bt
  • stdlib/test/string_advanced_methods_test.bt
  • stdlib/test/string_interpolation_test.bt
  • stdlib/test/string_new_methods_test.bt
  • stdlib/test/string_operations_test.bt
  • stdlib/test/string_quote_escape_test.bt
  • stdlib/test/system_test.bt
  • stdlib/test/test_case_assertion_test.bt
  • stdlib/test/test_runner_test.bt
  • stdlib/test/tier2_block_round_trip_test.bt
  • stdlib/test/times_repeat_simple_test.bt
  • stdlib/test/tuple_test.bt
  • stdlib/test/typed_classes_test.bt
  • stdlib/test/unary_messages_test.bt
  • stdlib/test/unicode_test.bt
  • stdlib/test/value_object_self_send_test.bt
  • stdlib/test/value_object_test.bt
  • stdlib/test/value_subclass_test.bt
  • stdlib/test/value_type_local_vars_test.bt
  • stdlib/test/value_type_multi_expr_test.bt
  • stdlib/test/value_type_non_local_return_test.bt
  • stdlib/test/value_type_update_test.bt
  • stdlib/test/workspace_interface_test.bt

- error_counter.bt: add missing license header
- nlr_baz.bt: remove stale comment that contradicted implementation
  (the ^ was removed by the lint fix; comment about 'do not simplify to
  x + x' no longer applies since the body is now x + x per project rules)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jamesc jamesc merged commit a422aac into main Feb 28, 2026
5 checks passed
@jamesc jamesc deleted the worktree-BT-964 branch February 28, 2026 14:45
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