| name | review |
| description | Review Ruby Fast LSP code changes and PRs using TigerStyle principles, project standards, and correctness checks. |
Code Review Skill
Use this skill when reviewing code changes, pull requests, or before merging code in the Ruby Fast LSP project. Provides a comprehensive checklist based on TigerStyle principles and project standards. Triggers: review, code review, PR review, pull request, check code, review changes.
Review Philosophy
"Code review is not about finding bugs. It's about maintaining code quality and sharing knowledge."
Goals of Review
- Correctness - Does it work as intended?
- Maintainability - Can others understand and modify it?
- Consistency - Does it follow project patterns?
- Safety - Are edge cases handled?
- Performance - Is it efficient enough?
Quick Review Checklist
Must Check (Blocking)
Should Check (Important)
Nice to Check (Optional)
Detailed Review Categories
1. TigerStyle Compliance
Function Length
fn massive_function() {
}
fn main_function() {
let step1 = do_step1();
let step2 = do_step2(step1);
finalize(step2)
}
Assertions
fn process(data: &Data) -> Result {
}
fn process(data: &Data) -> Result {
assert!(!data.is_empty(), "Data cannot be empty");
assert!(data.len() < MAX_SIZE, "Data exceeds maximum size");
}
Control Flow
fn traverse(node: &Node) {
traverse(node.left);
}
fn traverse(root: &Node) {
let mut stack = vec![root];
while let Some(node) = stack.pop() {
stack.extend(node.children());
}
}
2. Error Handling
Silent Failures
let _ = file.write(data);
file.write(data).context("Failed to write file")?;
if let Err(e) = file.write(data) {
warn!("Cache write failed: {}", e);
}
Result vs Option
fn parse_config(path: &Path) -> Option<Config>
fn parse_config(path: &Path) -> Result<Config, ConfigError>
Unwrap Usage
let doc = self.docs.get(&uri).unwrap();
let doc = self.docs.get(&uri).ok_or(QueryError::DocumentNotFound)?;
let doc = self.docs.get(&uri).expect("Document must exist after indexing");
3. Naming and Style
Naming Conventions
fn getDef() -> Def
let maxCnt = 10;
fn get_definition() -> Definition
let max_count = 10;
Units in Names
let timeout = 30;
let max_size = 1024;
let timeout_seconds = 30;
let max_size_bytes = 1024;
4. Architecture Compliance
Layer Dependencies
use crate::indexer::RubyIndex;
use crate::capabilities::definition;
Query Layer Usage
fn find_def(&self) {
let index = self.index.lock();
let result = index.definitions.get(&name);
}
fn find_def(&self) {
let query = IndexQuery::new(&self.index, &uri);
query.find_definitions_at_position(pos)
}
5. Testing
New Features Must Have Tests
pub fn new_feature() -> Result { ... }
pub fn new_feature() -> Result { ... }
Test Quality
#[test]
fn test_find_definition() {
let result = find_definition("MyClass");
assert!(result.is_some());
}
#[test]
fn test_find_definition() {
let result = find_definition("MyClass");
assert!(result.is_some());
let loc = result.unwrap();
assert_eq!(loc.uri.path(), "/src/my_class.rb");
assert_eq!(loc.range.start.line, 5);
}
6. Performance
Obvious Issues
for item in items {
process(item.clone());
}
for item in &items {
process(item);
}
Allocation Patterns
let mut results = Vec::new();
for i in 0..1000 {
results.push(compute(i));
}
let mut results = Vec::with_capacity(1000);
for i in 0..1000 {
results.push(compute(i));
}
Review Comments Guide
Blocking Comments
Use for issues that must be fixed:
**[BLOCKING]** This function is 120 lines. Please split into smaller
functions (max 70 lines per TigerStyle).
**[BLOCKING]** Unwrap on user input can panic. Use proper error handling.
Suggestion Comments
Use for improvements that aren't blocking:
**[Suggestion]** Consider using `Ustr` here since this string is
frequently compared.
**[Suggestion]** This could be simplified with `filter_map()`.
Question Comments
Use to understand intent:
**[Question]** Why is this error being ignored? Is this intentional?
**[Question]** Would it make sense to add a test for the edge case
where the list is empty?
Review Response Template
For Approvals
## Review: Approved
### Summary
Brief description of what was reviewed.
### Strengths
- Clean implementation of X
- Good test coverage for Y
### Minor Suggestions (non-blocking)
- Consider adding doc comment for public function
- Could simplify line 45 with iterator methods
Approved to merge!
For Changes Requested
## Review: Changes Requested
### Summary
Brief description of what was reviewed.
### Blocking Issues
1. **Function too long** (line 50-180): Split into smaller functions
2. **Missing error handling** (line 95): Don't ignore this error
### Non-blocking Suggestions
- Add test for empty input case
- Consider more descriptive variable name on line 30
Please address blocking issues before merge.
Automated Checks
Pre-Review Commands
Run before reviewing any PR:
cargo test
cargo clippy -- -D warnings
cargo fmt --check
cargo doc --no-deps
CI Requirements
Every PR should pass:
- All tests green
- No clippy warnings
- Properly formatted
- No new TODO/FIXME without issue reference
Common Review Findings
Most Frequent Issues
- Functions too long - Extract helpers
- Missing error context - Add
.context()
- Unwrap usage - Use
? or ok_or()
- No tests for new code - Add integration tests
- Inconsistent naming - Follow snake_case
Red Flags to Watch For
unwrap() anywhere except tests
// TODO without issue reference
- Functions over 70 lines
- Recursive functions
- Empty catch blocks / silent error swallowing
- Clone in hot loops
- Direct index access instead of IndexQuery