- STACK.md - Technologies and dependencies (.NET 4.7.2, NuGet, Costura.Fody) - ARCHITECTURE.md - Layered CLI with ICncMachine factory pattern - STRUCTURE.md - Directory layout and where to add new code - CONVENTIONS.md - C# style, naming, result wrapper pattern - TESTING.md - NUnit 3 + Moq, stubs, ignored FOCAS tests - INTEGRATIONS.md - FOCAS, LSV2, FTP, RSA licensing - CONCERNS.md - Blocking async, silent catch, no logging, Windows-only Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
122 lines
4.5 KiB
Markdown
122 lines
4.5 KiB
Markdown
# Coding Conventions
|
|
|
|
**Analysis Date:** 2026-05-18
|
|
|
|
## Naming Patterns
|
|
|
|
**Files:**
|
|
- PascalCase for all `.cs` files: `FanucMachine.cs`, `CncResult.cs`
|
|
- Interfaces: I-prefix PascalCase: `ICncMachine.cs`, `IFocasDialect.cs`
|
|
- Tests: `{Subject}Tests.cs` or `{Subject}IntegrationTests.cs`
|
|
- Config classes: `{Manufacturer}ConnectionConfig.cs`
|
|
|
|
**Classes:**
|
|
- PascalCase for all classes
|
|
- Sealed preferred for implementations (not open to inheritance)
|
|
- Examples: `NcProgramValidator.cs`, `CncResult.cs`
|
|
- Manufacturer-prefixed where relevant: `FanucMachine`, `HeidenhainMachine`, `SiemensMachine`
|
|
|
|
**Interfaces:**
|
|
- I-prefix strictly followed: `ICncMachine`, `IFanucMachine`, `ILicenseValidator`, `IFocasDialect`
|
|
|
|
**Fields:**
|
|
- Private: `_camelCase` with underscore prefix
|
|
- Example: `_config`, `_validator`, `_state`, `_hndl` in `Cnc/Fanuc/FanucMachine.cs`
|
|
- Constants (public): PascalCase — `AlarmSlots`, `TransferChunkSize` in `Cnc/Fanuc/FanucMachine.cs`
|
|
- Constants (private): can be UPPER_CASE or PascalCase
|
|
- Static readonly: `_camelCase` with underscore
|
|
|
|
**Properties:**
|
|
- PascalCase, read-only preferred
|
|
- Example: `Name`, `Comment`, `Content`, `Path` in `Cnc/Models/CncProgram.cs`
|
|
|
|
**Methods:**
|
|
- PascalCase for all public methods: `ConnectAsync()`, `ReadProgramAsync()`
|
|
- `Async` suffix on all methods returning `Task<T>` or `Task`
|
|
- Private helpers: `PascalCase` (same as public, no underscore)
|
|
- Example: `NcProgramValidator.cs`
|
|
|
|
**Enums:**
|
|
- PascalCase for type name, PascalCase for values
|
|
- Examples: `CncManufacturer.Fanuc`, `ConnectionState.Connected`, `FanucTransport.Ethernet`
|
|
|
|
## Code Style
|
|
|
|
**Formatting:**
|
|
- 4-space indentation
|
|
- Allman brace style (opening brace on new line for classes and methods)
|
|
- Example: `Cnc/Fanuc/FanucMachine.cs`
|
|
- Single-line property getters: inline `{ get { return _x; } }`
|
|
- No `.editorconfig` or StyleCop — conventions enforced by practice
|
|
|
|
**String Formatting:**
|
|
- `string.Format()` for parameterized messages (not `$""` interpolation)
|
|
- Example: `Cnc/NcProgramValidator.cs` lines with format strings
|
|
- `+` concatenation for console output in `Program.cs`
|
|
|
|
**Async:**
|
|
- `default` parameter for `CancellationToken` on async methods
|
|
- `ConfigureAwait(false)` on library-level code
|
|
- `Task.Run()` for blocking FOCAS calls in async context (RunGuardedAsync pattern)
|
|
|
|
## Import Organization
|
|
|
|
**Order:**
|
|
1. System namespaces
|
|
2. External packages
|
|
3. Internal project namespaces
|
|
|
|
No path aliases (not applicable to .NET Framework / no source generators).
|
|
|
|
## Error Handling
|
|
|
|
**Patterns:**
|
|
- Null guards at constructor: `if (config == null) throw new ArgumentNullException("config")`
|
|
- Example: `Cnc/Fanuc/FanucMachine.cs`
|
|
- Null-coalescing for optional deps: `_validator = validator ?? new NcProgramValidator(...)`
|
|
- `CncResult<T>` wrapper for all CNC operations (not exceptions)
|
|
- Exit codes at CLI boundary: -100 to -208 in `Program.cs`
|
|
- `try/finally` with `connected` flag for connection cleanup in `Program.cs`
|
|
|
|
**Result Wrapper Factories:**
|
|
- `CncResult<T>.Ok(value)` — success
|
|
- `CncResult<T>.Fail(errors)` — failure with error list
|
|
- `CncResult<T>.Cancelled()` — cancellation
|
|
- `CncResult<T>.OkWithWarnings(value, errors)` — partial success
|
|
|
|
## Logging
|
|
|
|
**Framework:** None — `Console.WriteLine` only
|
|
|
|
**Patterns:**
|
|
- User-facing output: `Console.WriteLine()` in `Program.cs`
|
|
- Error output: same Console (no stderr separation)
|
|
- No log levels, no timestamps, no structured logging
|
|
- Debug mode via `-debug=` arg keeps terminal open post-operation
|
|
|
|
## Comments
|
|
|
|
**When to Comment:**
|
|
- Document intent/constraints, not obvious code
|
|
- Example: `NcProgramValidator.cs` — "Name-format check (uses just the bare filename without path)"
|
|
- Separator line style for section breaks: `// ── private helpers ─────────────────`
|
|
- Example: `NcProgramValidator.cs`
|
|
|
|
**XML Doc Comments:**
|
|
- Sparse; only on public classes and key methods
|
|
- Format: `/// <summary>Brief description.</summary>`
|
|
- Examples: `NcProgramValidator.cs`, `CncResult.cs`, `ValidationResult.cs`
|
|
|
|
**No TODO/FIXME comments found in codebase** — known deferred work tracked in STATE.md.
|
|
|
|
## Function Design
|
|
|
|
- Private async methods wrap blocking/mixed code with semaphore locking (RunGuardedAsync pattern)
|
|
- Example: `Cnc/Fanuc/FanucMachine.cs` RunGuardedAsync
|
|
- Large transfer methods split into chunked helpers (`TransferChunked`, `UploadProgramByIdentifier`)
|
|
- Interface/implementation pairs for all protocol clients (I-prefix interface + concrete)
|
|
|
|
---
|
|
|
|
*Conventions analysis: 2026-05-18*
|
|
*Update when style decisions change*
|