Coding Style
Non-negotiable coding conventions enforced by CLAUDE.md.
CLAUDE.md in the sharp-runtime
repository. They are non-negotiable. All new code must follow them exactly.
Zero Warnings Policy
The project must compile with zero warnings. The CMakeLists.txt enables strict warning flags. Any code that introduces a new warning must be fixed before merging.
Test Requirement
New features must include focused tests in their owning module. Run that component's test executable during development; run scripts/run_component_tests.sh build after configuring All for a repository-wide change.
C++ Standard
C++23 is required. Use C++23 features freely — the project explicitly targets GCC 13+, Clang 17+, and MSVC 2022 17.5+.
Namespace Syntax
Use C++17 nested namespace syntax, not the older nested braces form:
// Correct
namespace System::Collections::Generic {
class List { ... };
}
// Wrong — do not use
namespace System {
namespace Collections {
namespace Generic {
class List { ... };
}
}
}
Property Naming
All properties must use the getXxxProperty() / setXxxProperty()
naming convention with the Prop.hpp macros:
// In .hpp
DDATA(int, Width) // declares width_, getWidthProperty(), setWidthProperty()
DGETTER(int, Area) // declares getAreaProperty() only (read-only)
// In .cpp
IDATA(MyClass, int, Width) // implements getter + setter
IGETTER(MyClass, int, Area, width_ * height_) // implements computed getter
Static properties use DGETTERSTATIC / IGETTERSTATIC.
Platform Guards
POSIX headers (<unistd.h>, <sys/socket.h>, etc.)
must only appear in .cpp files, never in .hpp files.
Platform-specific code must be guarded:
#ifdef _WIN32
// Windows-specific
#elif defined(__EMSCRIPTEN__)
// Emscripten-specific
#else
// POSIX (Linux, macOS, Android)
#endif
SPDX License Headers
Every file must start with the SPDX header:
// SPDX-License-Identifier: MIT
// Copyright (C) [year] [author]
// Based on .NET Runtime (MIT License)
GetTypeName Macros
Every class that inherits System::Object must implement GetTypeName()
using the macros:
// In .hpp class body:
GetTypeNameHPP();
// In .cpp:
GetTypeNameCPP(ClassName, "Namespace.ClassName")
File Structure
- Headers in
modules/<module>/include/, mirroring the namespace hierarchy - Implementations in the same module's
src/directory - Tests in the same module's
tests/directory (one test file per class is typical) - Cross-module scenarios only in
tests/integration/ - Each module declares its public, private, and test-only dependencies in its local
CMakeLists.txt - File names match class names exactly
Header Guards
Use #pragma once (not traditional #ifndef guards).
Status Doxygen Comments
Each class header should include a Doxygen comment with its implementation status:
/**
* @brief Short description.
* @status Implemented | Partial | Stub | Todo | Verified
*/
Naming Conventions
| What | Convention | Example |
|---|---|---|
| Classes | PascalCase | MyClass |
| Methods | PascalCase | DoSomething() |
| Private fields | camelCase + underscore | myField_ |
| Property backing field | camelCase + underscore | width_ |
| Property getter | get + PascalCase + Property | getWidthProperty() |
| Property setter | set + PascalCase + Property | setWidthProperty(v) |
| Local variables | camelCase | localVar |
| Namespaces | PascalCase | System::IO |