primer commit
This commit is contained in:
172
.claude/commands/lint-clang-tidy.md
Normal file
172
.claude/commands/lint-clang-tidy.md
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
description: Ejecuta clang-tidy en archivos C++ y analiza los resultados
|
||||
---
|
||||
|
||||
# Lint clang-tidy Command
|
||||
|
||||
Ejecuta análisis estático con clang-tidy en archivos C++ específicos, analiza los resultados inteligentemente, e identifica issues reales vs falsos positivos.
|
||||
|
||||
## Propósito
|
||||
|
||||
clang-tidy detecta:
|
||||
- Oportunidades de modernización C++ (auto, range-for, etc.)
|
||||
- Problemas de legibilidad del código
|
||||
- Potenciales bugs y memory leaks
|
||||
- Optimizaciones de performance
|
||||
- Violaciones de mejores prácticas
|
||||
|
||||
## Workflow de Ejecución
|
||||
|
||||
1. **Solicitar archivos al usuario** (si no se especifican)
|
||||
- Pedir rutas de archivos `.cpp` o `.hpp` a analizar
|
||||
- Validar que los archivos existen
|
||||
|
||||
2. **Verificar build directory**
|
||||
- Confirmar que `build/compile_commands.json` existe
|
||||
- Si no existe, informar al usuario que debe compilar primero
|
||||
|
||||
3. **Ejecutar clang-tidy (sin --fix)**
|
||||
```bash
|
||||
tools/linter/run_clang-tidy.sh archivo1.cpp archivo2.hpp
|
||||
```
|
||||
|
||||
4. **Capturar y analizar salida**
|
||||
- Parsear mensajes de error/warning
|
||||
- Clasificar por categoría (modernize, readability, performance, bugprone, etc.)
|
||||
- Identificar falsos positivos conocidos
|
||||
|
||||
5. **Presentar resumen al usuario**
|
||||
- Agrupar por tipo de issue
|
||||
- Separar "Críticos" vs "Recomendaciones" vs "Falsos Positivos"
|
||||
- Mostrar líneas de código afectadas con contexto
|
||||
|
||||
6. **Ofrecer acciones**
|
||||
- Preguntar si aplicar `--fix` automáticamente
|
||||
- Si el usuario acepta, ejecutar con `--fix` y recompilar
|
||||
|
||||
## Falsos Positivos Conocidos
|
||||
|
||||
Ignorar o marcar como "Opcional" estos casos:
|
||||
|
||||
### `readability-magic-numbers` / `cppcoreguidelines-avoid-magic-numbers`
|
||||
- **Contexto:** Game constants (block sizes, velocities, timers)
|
||||
- **Ejemplo:** `const int BLOCK = 16;`, `player.vx = 3.0F;`
|
||||
- **Acción:** Marcar como "Opcional - Game constant"
|
||||
|
||||
### `modernize-use-trailing-return-type`
|
||||
- **Contexto:** Funciones con tipos de retorno simples
|
||||
- **Ejemplo:** `int getValue() { return x_; }`
|
||||
- **Acción:** Marcar como "Opcional - Style preference"
|
||||
|
||||
### Errores en `defaults.hpp`
|
||||
- **Contexto:** Archivos de constantes del juego
|
||||
- **Acción:** Ignorar completamente, mencionar al usuario que es conocido
|
||||
|
||||
### `readability-identifier-length`
|
||||
- **Contexto:** Variables cortas comunes en loops o coordenadas (`x`, `y`, `i`, `j`)
|
||||
- **Acción:** Marcar como "Opcional - Common convention"
|
||||
|
||||
## Categorización de Issues
|
||||
|
||||
### 🔴 Críticos (Requieren atención)
|
||||
- `bugprone-*`: Potenciales bugs
|
||||
- `cert-*`: Security issues
|
||||
- Memory leaks y null pointer dereferences
|
||||
- Undefined behavior
|
||||
|
||||
### 🟡 Recomendados (Mejoran calidad)
|
||||
- `modernize-*`: C++20 modernization
|
||||
- `performance-*`: Optimizaciones
|
||||
- `readability-*`: Mejoras de legibilidad (excepto magic-numbers)
|
||||
|
||||
### ⚪ Opcionales (A criterio)
|
||||
- `readability-magic-numbers` en game constants
|
||||
- `modernize-use-trailing-return-type`
|
||||
- `readability-identifier-length` para `x`, `y`, `i`, `j`
|
||||
|
||||
### ⚫ Ignorar (Falsos positivos)
|
||||
- Errores en `defaults.hpp`
|
||||
- Issues en carpeta `external/`
|
||||
- Warnings en headers del sistema
|
||||
|
||||
## Formato de Reporte al Usuario
|
||||
|
||||
```
|
||||
=== clang-tidy Analysis Results ===
|
||||
|
||||
📁 Archivos analizados:
|
||||
- source/game/entities/player.cpp
|
||||
- source/game/entities/player.hpp
|
||||
|
||||
🔴 Críticos (2):
|
||||
player.cpp:145 [bugprone-use-after-move] - Uso de variable después de std::move()
|
||||
player.cpp:230 [cert-err58-cpp] - Excepción en inicialización estática
|
||||
|
||||
🟡 Recomendados (5):
|
||||
player.cpp:67 [modernize-use-auto] - Puede usar 'auto' en lugar de tipo explícito
|
||||
player.cpp:102 [performance-unnecessary-copy-initialization] - Copia innecesaria
|
||||
player.hpp:23 [readability-redundant-access-specifiers] - Especificador de acceso redundante
|
||||
|
||||
⚪ Opcionales (3):
|
||||
player.cpp:88 [readability-magic-numbers] - Magic number '16' (Game constant: BLOCK size)
|
||||
player.cpp:120 [modernize-use-trailing-return-type] - Style preference
|
||||
|
||||
✅ Total: 10 issues (2 críticos, 5 recomendados, 3 opcionales)
|
||||
|
||||
---
|
||||
|
||||
💡 Recomendaciones:
|
||||
1. Corregir los 2 issues críticos manualmente
|
||||
2. Aplicar --fix para 5 recomendaciones (revisa cambios antes de commitear)
|
||||
3. Los opcionales son aceptables en código de juego
|
||||
|
||||
¿Deseas aplicar fixes automáticos para los issues recomendados? (y/n)
|
||||
```
|
||||
|
||||
## Aplicar Fixes Automáticos
|
||||
|
||||
Si el usuario acepta:
|
||||
|
||||
1. **Ejecutar con --fix**
|
||||
```bash
|
||||
tools/linter/run_clang-tidy.sh --fix archivo1.cpp archivo2.hpp
|
||||
```
|
||||
|
||||
2. **Informar cambios**
|
||||
- Listar archivos modificados
|
||||
- Recomendar revisión manual
|
||||
|
||||
3. **Recompilar**
|
||||
```bash
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
4. **Verificar compilación exitosa**
|
||||
- Si falla, informar errores
|
||||
- Sugerir revertir cambios si es necesario
|
||||
|
||||
## Notas Importantes
|
||||
|
||||
- **Siempre analizar sin --fix primero** para revisar cambios propuestos
|
||||
- **Requiere build/compile_commands.json** - el usuario debe haber compilado antes
|
||||
- **Contexto importa** - Game code tiene patrones legítimos que linters marcan como issues
|
||||
- **No aplicar --fix ciegamente** - Algunos fixes pueden romper lógica del juego
|
||||
- **Archivos específicos** - Siempre analizar archivos concretos, no todo el proyecto
|
||||
|
||||
## Integración con Otros Comandos
|
||||
|
||||
Este comando puede ser llamado desde:
|
||||
- `/refactor-class` - Después de refactorizar una clase
|
||||
- Manualmente por el usuario para análisis ad-hoc
|
||||
- Antes de commits importantes
|
||||
|
||||
---
|
||||
|
||||
**Uso:**
|
||||
```
|
||||
/lint-clang-tidy
|
||||
(El comando preguntará qué archivos analizar)
|
||||
|
||||
O especificar directamente:
|
||||
/lint-clang-tidy source/game/entities/player.cpp
|
||||
```
|
||||
275
.claude/commands/lint-cppcheck.md
Normal file
275
.claude/commands/lint-cppcheck.md
Normal file
@@ -0,0 +1,275 @@
|
||||
---
|
||||
description: Ejecuta cppcheck en código C++ y analiza resultados
|
||||
---
|
||||
|
||||
# Lint cppcheck Command
|
||||
|
||||
Ejecuta análisis estático con cppcheck en código C++, filtra noise, e identifica issues reales relacionados con bugs, memory safety y undefined behavior.
|
||||
|
||||
## Propósito
|
||||
|
||||
cppcheck detecta:
|
||||
- Memory leaks y resource leaks
|
||||
- Null pointer dereferences
|
||||
- Buffer overflows y array bounds issues
|
||||
- Uninitialized variables
|
||||
- Dead code y unused functions
|
||||
- Style issues y code smells
|
||||
- Undefined behavior
|
||||
|
||||
## Workflow de Ejecución
|
||||
|
||||
1. **Solicitar archivos/rutas al usuario** (si no se especifican)
|
||||
- Pedir rutas de archivos `.cpp`/`.hpp` o carpetas a analizar
|
||||
- Preguntar nivel de análisis (warning/all/unused)
|
||||
- Default: `-w` (warning, style, performance)
|
||||
|
||||
2. **Validar precondiciones**
|
||||
- Confirmar que los archivos/carpetas existen
|
||||
- Si no existe `build/compile_commands.json`, el script lo generará automáticamente
|
||||
|
||||
3. **Ejecutar cppcheck**
|
||||
```bash
|
||||
# Para archivo específico
|
||||
tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp
|
||||
|
||||
# Para carpeta
|
||||
tools/linter/run_cppcheck.sh -w --path source/game/entities/
|
||||
|
||||
# Proyecto completo (LENTO)
|
||||
tools/linter/run_cppcheck.sh -w
|
||||
```
|
||||
|
||||
4. **Leer archivo de resultados**
|
||||
- `-w`: `tools/linter/cppcheck-result-warning-style-performance.txt`
|
||||
- `-a`: `tools/linter/cppcheck-result-all.txt`
|
||||
- `-u`: `tools/linter/cppcheck-result-unusedFunction.txt`
|
||||
|
||||
5. **Analizar y clasificar issues**
|
||||
- Parsear formato de cppcheck: `[archivo:línea]: (severidad) mensaje`
|
||||
- Filtrar falsos positivos conocidos
|
||||
- Agrupar por categoría
|
||||
|
||||
6. **Presentar resumen al usuario**
|
||||
- Mostrar issues críticos primero
|
||||
- Explicar contexto cuando sea relevante
|
||||
- Sugerir acciones correctivas
|
||||
|
||||
## Niveles de Análisis
|
||||
|
||||
### `-w` / `--warning` (Recomendado para uso diario)
|
||||
- **Velocidad:** Rápido
|
||||
- **Checks:** warning, style, performance
|
||||
- **Uso:** Refactoring diario, antes de commits
|
||||
- **Ejemplo:** `tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp`
|
||||
|
||||
### `-a` / `--all` (Análisis exhaustivo)
|
||||
- **Velocidad:** Lento
|
||||
- **Checks:** Todos los checks disponibles
|
||||
- **Uso:** Después de cambios mayores, auditorías de código
|
||||
- **Ejemplo:** `tools/linter/run_cppcheck.sh -a --path source/game/`
|
||||
|
||||
### `-u` / `--unused` (Funciones no usadas)
|
||||
- **Velocidad:** Medio
|
||||
- **Checks:** unusedFunction
|
||||
- **Uso:** Limpieza de código muerto
|
||||
- **Ejemplo:** `tools/linter/run_cppcheck.sh -u`
|
||||
- **Nota:** Requiere análisis de proyecto completo
|
||||
|
||||
## Falsos Positivos Conocidos
|
||||
|
||||
### `unusedFunction` en métodos públicos
|
||||
- **Contexto:** Métodos de API pública, callbacks, getters/setters
|
||||
- **Ejemplo:** `Player::getX()` usado desde múltiples lugares
|
||||
- **Acción:** Ignorar si el método es parte de la interfaz pública
|
||||
|
||||
### `passedByValue` para tipos pequeños
|
||||
- **Contexto:** SDL_FRect, SDL_Point, enums, small structs
|
||||
- **Ejemplo:** `void setPos(SDL_FPoint pos)`
|
||||
- **Acción:** Aceptable para tipos ≤ 16 bytes en game code
|
||||
|
||||
### `constParameter` en APIs consistentes
|
||||
- **Contexto:** Parámetros que no se modifican pero mantienen consistencia de API
|
||||
- **Acción:** Opcional, depende de estilo del proyecto
|
||||
|
||||
### `variableScope` en inicializaciones complejas
|
||||
- **Contexto:** Variables declaradas antes de inicialización compleja
|
||||
- **Acción:** Revisar caso por caso, puede ser falso positivo
|
||||
|
||||
## Categorización de Issues
|
||||
|
||||
### 🔴 Críticos (Requieren corrección inmediata)
|
||||
- `error`: Bugs confirmados
|
||||
- `memleakOnRealloc`: Memory leaks
|
||||
- `nullPointer`: Null pointer dereferences
|
||||
- `bufferAccessOutOfBounds`: Buffer overflows
|
||||
- `uninitvar`: Variables no inicializadas
|
||||
- `useAfterFree`: Use-after-free
|
||||
|
||||
### 🟠 Advertencias (Revisar y corregir)
|
||||
- `warning`: Potenciales problemas
|
||||
- `memleak`: Posibles memory leaks
|
||||
- `resourceLeak`: Resource leaks (file handles, etc.)
|
||||
- `doubleFree`: Double free
|
||||
- `arrayIndexOutOfBounds`: Array bounds issues
|
||||
|
||||
### 🟡 Estilo (Mejoran calidad)
|
||||
- `style`: Code smells
|
||||
- `unusedVariable`: Variables no usadas
|
||||
- `redundantAssignment`: Asignaciones redundantes
|
||||
- `unreadVariable`: Variables escritas pero no leídas
|
||||
|
||||
### 🟢 Performance (Optimizaciones)
|
||||
- `performance`: Optimizaciones de rendimiento
|
||||
- `passedByValue`: Pasar por const& en vez de value
|
||||
- `postfixOperator`: Usar prefix++ en vez de postfix++
|
||||
|
||||
### ⚪ Informativo (Opcional)
|
||||
- `information`: Información general
|
||||
- `portability`: Problemas de portabilidad
|
||||
- `unusedFunction`: Funciones no usadas (revisar contexto)
|
||||
|
||||
## Formato de Reporte al Usuario
|
||||
|
||||
```
|
||||
=== cppcheck Analysis Results ===
|
||||
|
||||
📁 Archivos analizados: source/game/entities/player.cpp
|
||||
📊 Nivel: warning + style + performance
|
||||
📝 Resultados: tools/linter/cppcheck-result-warning-style-performance.txt
|
||||
|
||||
🔴 Errores críticos (2):
|
||||
player.cpp:156 [error:uninitvar] - Variable 'velocity' no inicializada
|
||||
player.cpp:234 [error:nullPointer] - Posible null pointer dereference
|
||||
|
||||
🟠 Advertencias (3):
|
||||
player.cpp:89 [warning:memleak] - Posible memory leak en 'sprite_'
|
||||
player.cpp:178 [warning:arrayIndexOutOfBounds] - Índice fuera de límites
|
||||
|
||||
🟡 Estilo (4):
|
||||
player.cpp:45 [style:unusedVariable] - Variable 'temp' declarada pero no usada
|
||||
player.cpp:102 [style:redundantAssignment] - Asignación redundante a 'x_'
|
||||
|
||||
🟢 Performance (2):
|
||||
player.cpp:67 [performance:passedByValue] - Pasar 'data' por const& (8 bytes - FALSO POSITIVO)
|
||||
player.hpp:34 [performance:postfixOperator] - Usar prefix++ en lugar de postfix++
|
||||
|
||||
✅ Total: 11 issues
|
||||
- 2 críticos ❗
|
||||
- 3 advertencias
|
||||
- 4 estilo
|
||||
- 2 performance (1 falso positivo)
|
||||
|
||||
---
|
||||
|
||||
💡 Acción requerida:
|
||||
1. ✅ Corregir 2 errores críticos INMEDIATAMENTE
|
||||
2. ⚠️ Revisar 3 advertencias y corregir si aplica
|
||||
3. 🔧 Considerar 4 mejoras de estilo
|
||||
4. ⚡ 1 optimización real de performance (ignorar passedByValue)
|
||||
|
||||
📄 Detalles completos en: tools/linter/cppcheck-result-warning-style-performance.txt
|
||||
```
|
||||
|
||||
## Acciones Post-Análisis
|
||||
|
||||
### Si hay errores críticos:
|
||||
1. **Mostrar código afectado** con contexto
|
||||
2. **Explicar el problema** en términos claros
|
||||
3. **Sugerir corrección** específica
|
||||
4. **Ofrecer aplicar fix** si es sencillo
|
||||
|
||||
### Si solo hay warnings/style:
|
||||
1. **Resumir issues** por categoría
|
||||
2. **Indicar prioridades** (qué corregir primero)
|
||||
3. **Explicar falsos positivos** identificados
|
||||
4. **Preguntar si aplicar fixes** para issues simples
|
||||
|
||||
### Si no hay issues:
|
||||
```
|
||||
✅ ¡Código limpio! No se encontraron issues.
|
||||
```
|
||||
|
||||
## Ejemplos de Correcciones Comunes
|
||||
|
||||
### Uninitialized variable
|
||||
```cpp
|
||||
// ❌ Antes
|
||||
int velocity;
|
||||
if (condition) {
|
||||
velocity = 10;
|
||||
}
|
||||
use(velocity); // Error: puede estar no inicializada
|
||||
|
||||
// ✅ Después
|
||||
int velocity{0}; // Inicializar en declaración
|
||||
if (condition) {
|
||||
velocity = 10;
|
||||
}
|
||||
use(velocity);
|
||||
```
|
||||
|
||||
### Memory leak
|
||||
```cpp
|
||||
// ❌ Antes
|
||||
void loadTexture() {
|
||||
texture_ = new SDL_Texture(...);
|
||||
if (error) return; // Leak si hay error después
|
||||
}
|
||||
|
||||
// ✅ Después
|
||||
void loadTexture() {
|
||||
auto temp = std::make_unique<SDL_Texture>(...)
|
||||
if (error) return; // RAII - se libera automáticamente
|
||||
texture_ = std::move(temp);
|
||||
}
|
||||
```
|
||||
|
||||
### Null pointer dereference
|
||||
```cpp
|
||||
// ❌ Antes
|
||||
Player* player = getPlayer();
|
||||
player->update(); // Puede ser nullptr
|
||||
|
||||
// ✅ Después
|
||||
Player* player = getPlayer();
|
||||
if (player != nullptr) {
|
||||
player->update();
|
||||
}
|
||||
```
|
||||
|
||||
## Integración con Workflow
|
||||
|
||||
### Cuándo ejecutar:
|
||||
|
||||
1. **Después de refactoring** - Verificar que no se introdujeron bugs
|
||||
2. **Antes de commit** - Análisis `-w` rápido
|
||||
3. **Antes de PR** - Análisis `-a` completo
|
||||
4. **Periódicamente** - Análisis `-u` para limpieza de código
|
||||
|
||||
### Integración con `/refactor-class`:
|
||||
|
||||
El comando `/refactor-class` ejecuta automáticamente:
|
||||
```bash
|
||||
tools/linter/run_cppcheck.sh -w --path <archivo_refactorizado>
|
||||
```
|
||||
|
||||
## Notas Importantes
|
||||
|
||||
- **Genera archivos de salida** en `tools/linter/cppcheck-result-*.txt`
|
||||
- **Auto-genera compile_commands.json** si no existe
|
||||
- **Paralelización automática** usa N-1 cores
|
||||
- **Suppressions file** excluye external/ y system headers
|
||||
- **Contexto importa** - Revisar falsos positivos manualmente
|
||||
- **No modifica código** - Solo reporta, no aplica fixes automáticos
|
||||
|
||||
---
|
||||
|
||||
**Uso:**
|
||||
```
|
||||
/lint-cppcheck
|
||||
(El comando preguntará qué analizar y qué nivel usar)
|
||||
|
||||
O especificar directamente:
|
||||
/lint-cppcheck source/game/entities/player.cpp
|
||||
```
|
||||
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