primer commit
This commit is contained in:
279
.claude/commands/refactor-class.md
Normal file
279
.claude/commands/refactor-class.md
Normal file
@@ -0,0 +1,279 @@
|
||||
---
|
||||
description: Refactoriza una clase C++ aplicando buenas prácticas de estilo
|
||||
---
|
||||
|
||||
# Refactor Class Command
|
||||
|
||||
Refactoriza una clase C++ siguiendo estas reglas de estilo y buenas prácticas:
|
||||
|
||||
## Reglas de Refactorización
|
||||
|
||||
### 1. Inicialización de Variables Miembro
|
||||
- **Inicializar en la declaración** todas las variables "simples" que no tengan dependencias complejas:
|
||||
- Tipos primitivos: `int`, `float`, `bool`, etc.
|
||||
- Enumeraciones: valores de enum class
|
||||
- Valores por defecto conocidos: `0`, `0.0F`, `false`, `nullptr`, etc.
|
||||
- **NO inicializar en declaración** si:
|
||||
- Dependen de otros miembros
|
||||
- Requieren llamadas a funciones complejas
|
||||
- Son punteros a recursos que necesitan construcción específica
|
||||
|
||||
### 2. Structs con Valores por Defecto
|
||||
- **Todos los miembros de structs** deben tener valores por defecto:
|
||||
- Tipos primitivos: `int x{0}`, `float y{0.0F}`, `bool flag{false}`
|
||||
- Strings: `std::string name{}`
|
||||
- Punteros: `Type* ptr{nullptr}`
|
||||
- **Ventajas**: Inicialización segura, evita valores indefinidos
|
||||
|
||||
### 3. Arrays C-style → std::array
|
||||
- Convertir **todos** los arrays C-style a `std::array`:
|
||||
- `Type array[N]` → `std::array<Type, N> array{}`
|
||||
- Inicializar con `{}` para zero-initialization
|
||||
- Agregar `#include <array>` si no existe
|
||||
- **Ventajas**: type-safety, size(), métodos STL, sin decay a pointer
|
||||
|
||||
### 3. Reorganización de la Clase
|
||||
|
||||
#### Orden de Secciones
|
||||
1. **public** (primero)
|
||||
2. **private** (después)
|
||||
|
||||
#### Dentro de cada sección (private principalmente)
|
||||
1. **Estructuras y enumeraciones** (tipos anidados)
|
||||
2. **Constantes** (static constexpr)
|
||||
3. **Métodos** (funciones miembro)
|
||||
4. **Variables miembro** (al final)
|
||||
|
||||
### 4. Agrupación y Comentarios de Métodos
|
||||
- **En sección public**: Agrupar métodos relacionados funcionalmente
|
||||
- **Comentarios en línea** (a la derecha) para describir cada método/grupo
|
||||
- **Formato**: `void method(); // Descripción concisa`
|
||||
- **Espaciado**: Línea en blanco entre grupos funcionales
|
||||
|
||||
**Ejemplo:**
|
||||
```cpp
|
||||
public:
|
||||
static void init(...); // Inicialización singleton
|
||||
static void destroy(); // Destrucción singleton
|
||||
static auto get() -> T*; // Acceso al singleton
|
||||
|
||||
void render(); // Renderizado
|
||||
void update(float dt); // Actualización lógica
|
||||
|
||||
auto isActive() -> bool; // Consulta estado
|
||||
```
|
||||
|
||||
### 5. Comentarios de Variables
|
||||
- **Posición**: A la derecha de la variable/grupo
|
||||
- **Formato**: `// Descripción concisa`
|
||||
- Agrupar variables relacionadas con un comentario común
|
||||
|
||||
### 6. Constructores en Structs
|
||||
- **Eliminar constructores por defecto redundantes** en structs:
|
||||
- Si todos los miembros tienen inicialización en declaración
|
||||
- Y no hay múltiples constructores
|
||||
- Eliminar `explicit Type() = default;`
|
||||
- El compilador generará automáticamente un constructor por defecto
|
||||
|
||||
**Ejemplo:**
|
||||
```cpp
|
||||
struct Data {
|
||||
int x{0};
|
||||
std::string name{};
|
||||
// NO NECESITA: explicit Data() = default;
|
||||
};
|
||||
```
|
||||
|
||||
### 7. Includes Necesarios
|
||||
- Agregar includes faltantes según lo que se use
|
||||
- Mantener orden alfabético si es posible
|
||||
|
||||
### 8. Header Guards
|
||||
- **Usar `#pragma once`** en todas las cabeceras (`.hpp`)
|
||||
- **NO usar** `#ifndef`/`#define`/`#endif` tradicionales
|
||||
- `#pragma once` debe ser la primera línea del archivo (antes de includes)
|
||||
- **Ventajas**: Más simple, menos propenso a errores, ampliamente soportado
|
||||
|
||||
## Ejemplo de Aplicación
|
||||
|
||||
### Antes:
|
||||
```cpp
|
||||
class Example {
|
||||
private:
|
||||
struct Data {
|
||||
std::string name;
|
||||
int value;
|
||||
};
|
||||
|
||||
int counter_;
|
||||
bool flag_;
|
||||
float values_[10];
|
||||
|
||||
public:
|
||||
Example();
|
||||
void update();
|
||||
};
|
||||
|
||||
// Constructor
|
||||
Example::Example()
|
||||
: counter_(0),
|
||||
flag_(false) {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
values_[i] = 0.0F;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Después:
|
||||
```cpp
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
class Example {
|
||||
public:
|
||||
Example() = default; // Ya no necesita inicializar
|
||||
void update();
|
||||
|
||||
private:
|
||||
// Tipos anidados
|
||||
struct Data {
|
||||
std::string name{}; // Nombre con valor por defecto
|
||||
int value{0}; // Valor inicializado
|
||||
};
|
||||
|
||||
// Variables miembro
|
||||
int counter_{0}; // Contador de frames
|
||||
bool flag_{false}; // Estado activo
|
||||
std::array<float, 10> values_{}; // Buffer de valores
|
||||
};
|
||||
```
|
||||
|
||||
## Tareas a Realizar
|
||||
|
||||
Cuando uses este comando en una clase específica:
|
||||
|
||||
1. **Leer** el archivo `.hpp` y `.cpp` correspondiente
|
||||
2. **Verificar** que la cabecera use `#pragma once` (reemplazar `#ifndef`/`#define`/`#endif` si existen)
|
||||
3. **Identificar** structs y agregar valores por defecto a todos sus miembros
|
||||
4. **Identificar** variables que pueden inicializarse en declaración
|
||||
5. **Identificar** arrays C-style que convertir a std::array
|
||||
6. **Reorganizar** la estructura de la clase (public/private, agrupación)
|
||||
7. **Actualizar** el archivo `.cpp` eliminando inicializaciones redundantes
|
||||
8. **Compilar** para verificar sintaxis correcta
|
||||
9. **Ejecutar clang-tidy** (análisis, sin --fix) y revisar resultados
|
||||
10. **Ejecutar cppcheck** (nivel -w) y revisar resultados
|
||||
11. **Aplicar fixes apropiados** basados en análisis de linters
|
||||
12. **Recompilar** si se aplicaron fixes
|
||||
13. **Reportar resumen** al usuario: cambios + hallazgos de linters
|
||||
|
||||
## Workflow de Linters (Pasos 9-12)
|
||||
|
||||
### Paso 9: Ejecutar clang-tidy
|
||||
|
||||
```bash
|
||||
tools/linter/run_clang-tidy.sh archivo.cpp archivo.hpp
|
||||
```
|
||||
|
||||
**Analizar resultados:**
|
||||
- Identificar issues críticos (bugprone, cert)
|
||||
- Separar recomendaciones válidas de falsos positivos
|
||||
- Ignorar: magic-numbers en game constants, defaults.hpp errors
|
||||
- Si hay issues críticos, informar al usuario y pausar
|
||||
- Si solo hay recomendaciones, continuar
|
||||
|
||||
### Paso 10: Ejecutar cppcheck
|
||||
|
||||
```bash
|
||||
tools/linter/run_cppcheck.sh -w --path archivo.cpp
|
||||
```
|
||||
|
||||
**Leer archivo de resultados:**
|
||||
- `tools/linter/cppcheck-result-warning-style-performance.txt`
|
||||
- Identificar errores críticos (error, nullPointer, uninitvar)
|
||||
- Separar warnings de style issues
|
||||
- Filtrar falsos positivos (passedByValue para tipos pequeños, unusedFunction en API pública)
|
||||
- Si hay errores críticos, informar al usuario y pausar
|
||||
|
||||
### Paso 11: Aplicar Fixes
|
||||
|
||||
**Si hay issues aplicables:**
|
||||
|
||||
1. **Fixes automáticos de clang-tidy** (solo si son seguros):
|
||||
- modernize-use-auto
|
||||
- readability-redundant-access-specifiers
|
||||
- Performance optimizations claras
|
||||
|
||||
```bash
|
||||
tools/linter/run_clang-tidy.sh --fix archivo.cpp archivo.hpp
|
||||
```
|
||||
|
||||
2. **Fixes manuales necesarios:**
|
||||
- Inicializar variables no inicializadas
|
||||
- Corregir null pointer issues
|
||||
- Resolver memory leaks
|
||||
|
||||
3. **Documentar cambios** para el reporte final
|
||||
|
||||
### Paso 12: Recompilar
|
||||
|
||||
Si se aplicaron fixes en paso 11:
|
||||
|
||||
```bash
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
**Verificar:**
|
||||
- ✅ Compilación exitosa → Continuar a reporte
|
||||
- ❌ Errores → Informar al usuario, sugerir revisión manual
|
||||
|
||||
## Formato de Reporte Final (Paso 13)
|
||||
|
||||
```
|
||||
=== Refactor Completado: ClassName ===
|
||||
|
||||
📝 Cambios estructurales:
|
||||
✅ #pragma once aplicado
|
||||
✅ 3 structs actualizados con valores por defecto
|
||||
✅ 12 variables movidas a inicialización en declaración
|
||||
✅ 2 arrays C-style → std::array
|
||||
✅ Clase reorganizada (public primero, variables al final)
|
||||
✅ Constructor simplificado (elimina 12 inicializaciones redundantes)
|
||||
|
||||
🔍 Análisis de linters:
|
||||
|
||||
clang-tidy:
|
||||
✅ Sin issues críticos
|
||||
🟡 3 recomendaciones aplicadas automáticamente:
|
||||
- Modernize: use auto (2 lugares)
|
||||
- Readability: redundant specifier (1 lugar)
|
||||
⚪ 2 opcionales ignorados:
|
||||
- magic-numbers en game constants
|
||||
|
||||
cppcheck:
|
||||
✅ Sin errores
|
||||
🟡 2 style issues encontrados:
|
||||
- Unused variable 'temp' en línea 45 → Eliminada
|
||||
- Redundant assignment en línea 102 → Corregida
|
||||
|
||||
📊 Resultado:
|
||||
✅ Compilación exitosa
|
||||
✅ Todos los linters pasan sin issues críticos
|
||||
✅ Código refactorizado y verificado
|
||||
|
||||
💡 Próximos pasos:
|
||||
- Revisar cambios manualmente
|
||||
- Ejecutar tests si existen
|
||||
- Commitear con mensaje descriptivo
|
||||
```
|
||||
|
||||
## Notas Importantes
|
||||
|
||||
- **No cambiar lógica**: Solo refactorización estructural
|
||||
- **Mantener compatibilidad**: std::array usa misma sintaxis [] para acceso
|
||||
- **Formato consistente**: Respetar estilo del proyecto (comentarios, espaciado)
|
||||
- **Validar compilación**: Siempre verificar que compile después de cambios
|
||||
- **Linters integrados**: Análisis automático post-refactor para garantizar calidad
|
||||
- **Fixes inteligentes**: Solo aplicar --fix de clang-tidy si los cambios son seguros
|
||||
- **Contexto importa**: Game code tiene patrones legítimos (magic numbers, etc.)
|
||||
- **Falsos positivos**: Identificar y documentar, no corregir ciegamente
|
||||
Reference in New Issue
Block a user