Lint Tonel files for Smalltalk best practices before import
Analyze Tonel Smalltalk files for best practices before importing to Pharo. Checks for class prefixes, method length, instance variable count, and direct access violations.
/plugin marketplace add mumez/smalltalk-dev-plugin/plugin install smalltalk-dev@smalltalk-dev-marketplaceAnalyze Tonel files for Smalltalk best practices and code quality issues before importing to Pharo. Uses the smalltalk-validator MCP server to check code quality.
# Lint specific file
/st:lint src/MyPackage/MyClass.st
# Lint entire package
/st:lint src/MyPackage
# Lint all packages in src/
/st:lint src
The MCP server checks for the following Smalltalk best practices:
Rule: Classes should have a project-specific prefix to avoid name collisions.
Examples:
STUser, JSONParser, RedisClient (prefixed)User, Parser, Client (no prefix - potential collision)Exceptions:
Test)Rule: Methods should be concise and focused.
Limits:
Examples:
"✅ Good: Focused 5-line method"
Person >> fullName [
^ firstName, ' ', lastName
]
"⚠️ Warning: 20 lines (consider extracting helpers)"
Calculator >> complexCalculation [
"... 20 lines of logic ..."
]
"❌ Error: 30 lines in standard method"
DataProcessor >> process [
"... 30 lines - refactor needed ..."
]
Rule: Classes should have focused responsibilities with limited instance variables.
Limits:
Examples:
"✅ Good: 4 focused instance variables"
Class {
#name : #Person,
#instVars : [
'firstName',
'lastName',
'age',
'email'
]
}
"⚠️ Warning: 12 variables - consider splitting"
Class {
#name : #User,
#instVars : [
'firstName', 'lastName', 'email', 'phone',
'address', 'city', 'state', 'zip',
'role', 'permissions', 'preferences', 'settings'
]
}
Rule: Access instance variables through methods, not directly (except in initialization and accessors).
Rationale:
Examples:
"✅ Good: Access via method"
Person >> greet [
^ 'Hello, ', self firstName
]
"✅ OK: Direct access in initialize"
{ #category : #initialization }
Person >> initialize [
super initialize.
firstName := ''.
age := 0
]
"⚠️ Warning: Direct access in business logic"
{ #category : #operations }
Person >> processName [
^ firstName asUppercase "Should be: self firstName asUppercase"
]
This command uses the mcp__smalltalk-validator__lint_tonel_smalltalk_from_file MCP tool to perform linting.
TARGET="$1"
if [ -z "$TARGET" ]; then
echo "Error: No target specified"
echo "Usage: /st:lint <file-or-directory>"
exit 1
fi
# Collect files to lint
if [ -f "$TARGET" ]; then
FILES=("$TARGET")
elif [ -d "$TARGET" ]; then
FILES=($(find "$TARGET" -name "*.st" ! -name "package.st"))
else
echo "Error: $TARGET not found"
exit 1
fi
For each .st file (excluding package.st), call the MCP lint tool:
for file in "${FILES[@]}"; do
echo "Linting: $file"
# Call MCP lint tool
mcp__smalltalk-validator__lint_tonel_smalltalk_from_file "$file"
done
The MCP server returns lint results in this format:
{
"success": true,
"file_path": "/path/to/MyClass.st",
"issue_list": [
{
"severity": "warning",
"message": "No class prefix: Person (consider adding project prefix)",
"class_name": "Person",
"selector": null,
"is_class_method": false
},
{
"severity": "warning",
"message": "Method 'complexProcess' long: 22 lines (recommended: 15)",
"class_name": "Person",
"selector": "complexProcess",
"is_class_method": false
}
],
"issues_count": 2,
"warnings_count": 2,
"errors_count": 0
}
Display the lint results and exit with appropriate code:
# Exit codes
# 0: No issues
# 1: Warnings only
# 2: Errors found
/st:lint src/MyPackage/Person.st
The MCP tool will analyze the file and return issues found.
/st:lint src/MyPackage
Lints all .st files in the package directory.
# Recommended workflow
/st:lint src/MyPackage # Check code quality (MCP)
/st:import MyPackage /absolute/path/src # Import to Pharo
/st:test MyPackage-Tests # Run tests
/st:import: Run lint to ensure code quality/st:validate - Syntax validation (Tonel structure)/st:import - Import to Pharo (after linting)/st:test - Run tests (after import)When executing this command:
This command helps maintain high code quality and idiomatic Smalltalk style before importing to Pharo.