netejant capçaleres
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
|
||||||
|
```
|
||||||
@@ -160,8 +160,112 @@ Cuando uses este comando en una clase específica:
|
|||||||
5. **Identificar** arrays C-style que convertir a std::array
|
5. **Identificar** arrays C-style que convertir a std::array
|
||||||
6. **Reorganizar** la estructura de la clase (public/private, agrupación)
|
6. **Reorganizar** la estructura de la clase (public/private, agrupación)
|
||||||
7. **Actualizar** el archivo `.cpp` eliminando inicializaciones redundantes
|
7. **Actualizar** el archivo `.cpp` eliminando inicializaciones redundantes
|
||||||
8. **Verificar** que compile correctamente
|
8. **Compilar** para verificar sintaxis correcta
|
||||||
9. **Informar** al usuario de los cambios realizados
|
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
|
## Notas Importantes
|
||||||
|
|
||||||
@@ -169,3 +273,7 @@ Cuando uses este comando en una clase específica:
|
|||||||
- **Mantener compatibilidad**: std::array usa misma sintaxis [] para acceso
|
- **Mantener compatibilidad**: std::array usa misma sintaxis [] para acceso
|
||||||
- **Formato consistente**: Respetar estilo del proyecto (comentarios, espaciado)
|
- **Formato consistente**: Respetar estilo del proyecto (comentarios, espaciado)
|
||||||
- **Validar compilación**: Siempre verificar que compile después de cambios
|
- **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
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"Bash(cmake --build:*)"
|
"Bash(cmake --build:*)",
|
||||||
|
"Bash(test:*)",
|
||||||
|
"Bash(tools/linter/run_clang-tidy.sh:*)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
85
CLAUDE.md
85
CLAUDE.md
@@ -55,9 +55,15 @@ cmake --build build --clean-first
|
|||||||
|
|
||||||
**Important:** The build directory is `/Users/sergio/Gitea/jaildoctors_dilemma/build` and the output executable is placed in the project root directory.
|
**Important:** The build directory is `/Users/sergio/Gitea/jaildoctors_dilemma/build` and the output executable is placed in the project root directory.
|
||||||
|
|
||||||
### Linter (clang-tidy)
|
### Static Analysis Tools (Linters)
|
||||||
|
|
||||||
**IMPORTANT:** Always run the linter on specific files, NOT on the entire project, to avoid long execution times and errors in unrelated files.
|
This project uses two complementary static analysis tools for code quality:
|
||||||
|
|
||||||
|
#### clang-tidy (Modernization & Best Practices)
|
||||||
|
|
||||||
|
**Purpose:** Detects style issues, modernization opportunities, and potential bugs. Best for refactoring and applying C++20 best practices.
|
||||||
|
|
||||||
|
**IMPORTANT:** Always run on specific files, NOT on the entire project, to avoid long execution times and errors in unrelated files.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Analyze a specific file (RECOMMENDED)
|
# Analyze a specific file (RECOMMENDED)
|
||||||
@@ -73,7 +79,80 @@ tools/linter/run_clang-tidy.sh --fix source/game/entities/player.cpp
|
|||||||
tools/linter/run_clang-tidy.sh
|
tools/linter/run_clang-tidy.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** Running the linter on the entire project can produce errors in files like `defaults.hpp` that are unrelated to your changes. Always target specific files you're working on.
|
**Common clang-tidy Checks:**
|
||||||
|
- `modernize-*`: C++ modernization (use auto, range-for, etc.)
|
||||||
|
- `readability-*`: Code readability improvements
|
||||||
|
- `performance-*`: Performance optimizations
|
||||||
|
- `bugprone-*`: Potential bug detection
|
||||||
|
|
||||||
|
**Known False Positives:**
|
||||||
|
- `defaults.hpp`: May report errors in constant definitions
|
||||||
|
- `readability-magic-numbers`: Acceptable for game constants (block sizes, speeds, etc.)
|
||||||
|
- `cppcoreguidelines-avoid-magic-numbers`: Same as above, acceptable in game code
|
||||||
|
|
||||||
|
#### cppcheck (Bug Detection & Memory Safety)
|
||||||
|
|
||||||
|
**Purpose:** Detects bugs, memory leaks, undefined behavior, and style issues. Complementary to clang-tidy.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Warning, style, and performance analysis (RECOMMENDED for daily use)
|
||||||
|
tools/linter/run_cppcheck.sh -w --path source/game/entities/player.cpp
|
||||||
|
|
||||||
|
# Exhaustive analysis (slower, more thorough)
|
||||||
|
tools/linter/run_cppcheck.sh -a --path source/game/entities/
|
||||||
|
|
||||||
|
# Detect unused functions (whole project analysis)
|
||||||
|
tools/linter/run_cppcheck.sh -u
|
||||||
|
|
||||||
|
# Analyze entire project with warning level
|
||||||
|
tools/linter/run_cppcheck.sh -w
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output:** Results are saved in `tools/linter/cppcheck-result-*.txt`
|
||||||
|
|
||||||
|
**Common cppcheck Checks:**
|
||||||
|
- Memory leaks and resource management
|
||||||
|
- Null pointer dereferences
|
||||||
|
- Buffer overflows and array bounds
|
||||||
|
- Uninitialized variables
|
||||||
|
- Dead code and unused functions
|
||||||
|
|
||||||
|
**Known False Positives:**
|
||||||
|
- `unusedFunction`: May report false positives for callback functions or public API methods
|
||||||
|
- `passedByValue`: Acceptable for small types like SDL_FRect in game code
|
||||||
|
- `constParameter`: Not always applicable for API consistency
|
||||||
|
|
||||||
|
#### When to Use Each Tool
|
||||||
|
|
||||||
|
| Scenario | Tool | Reason |
|
||||||
|
|----------|------|--------|
|
||||||
|
| **Daily refactoring** | clang-tidy | Fast, auto-fixable issues |
|
||||||
|
| **Before committing** | Both | Comprehensive quality check |
|
||||||
|
| **After major changes** | cppcheck -a | Deep bug analysis |
|
||||||
|
| **Hunting memory leaks** | cppcheck | Specialized detection |
|
||||||
|
| **Code modernization** | clang-tidy --fix | Automatic C++20 upgrades |
|
||||||
|
|
||||||
|
#### Best Practices
|
||||||
|
|
||||||
|
1. **Run linters after compilation succeeds** - Fix compile errors first
|
||||||
|
2. **Analyze specific files** - Faster feedback, avoids unrelated errors
|
||||||
|
3. **Review before applying --fix** - Understand changes before accepting
|
||||||
|
4. **Context matters** - Game code may legitimately have "magic numbers" for gameplay constants
|
||||||
|
5. **Use both tools** - They catch different issues and complement each other
|
||||||
|
6. **Check suppressions file** - `tools/linter/cppcheck_suppressions` excludes external/ and system headers
|
||||||
|
|
||||||
|
#### Integration with Development Workflow
|
||||||
|
|
||||||
|
When refactoring code (especially with `/refactor-class` command):
|
||||||
|
1. Make structural changes
|
||||||
|
2. **Compile** to verify syntax
|
||||||
|
3. **Run clang-tidy** (without --fix) to identify issues
|
||||||
|
4. **Run cppcheck -w** to catch bugs
|
||||||
|
5. Review and fix legitimate issues
|
||||||
|
6. Apply automatic fixes if appropriate
|
||||||
|
7. Recompile and test
|
||||||
|
|
||||||
|
**Note:** The `/refactor-class` command automatically runs both linters after compilation and provides intelligent analysis of results.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -14,32 +14,29 @@ SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_F
|
|||||||
SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos)
|
SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos)
|
||||||
: SurfaceSprite(std::move(surface), pos),
|
: SurfaceSprite(std::move(surface), pos),
|
||||||
x_(pos.x),
|
x_(pos.x),
|
||||||
y_(pos.y),
|
y_(pos.y) { SurfaceSprite::pos_ = pos; }
|
||||||
flip_(SDL_FLIP_NONE) { SurfaceSprite::pos_ = pos; }
|
|
||||||
|
|
||||||
SurfaceMovingSprite::SurfaceMovingSprite()
|
SurfaceMovingSprite::SurfaceMovingSprite() { SurfaceSprite::clear(); }
|
||||||
: x_(0.0F),
|
|
||||||
y_(0.0F),
|
|
||||||
flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); }
|
|
||||||
|
|
||||||
SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface)
|
SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface)
|
||||||
: SurfaceSprite(std::move(surface)),
|
: SurfaceSprite(std::move(surface)) { SurfaceSprite::clear(); }
|
||||||
x_(0.0F),
|
|
||||||
y_(0.0F),
|
|
||||||
flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); }
|
|
||||||
|
|
||||||
// Reinicia todas las variables
|
// Reinicia todas las variables
|
||||||
void SurfaceMovingSprite::clear() {
|
void SurfaceMovingSprite::clear() {
|
||||||
x_ = 0.0F; // Posición en el eje X
|
// Resetea posición
|
||||||
y_ = 0.0F; // Posición en el eje Y
|
x_ = 0.0F;
|
||||||
|
y_ = 0.0F;
|
||||||
|
|
||||||
vx_ = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
|
// Resetea velocidad
|
||||||
vy_ = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
|
vx_ = 0.0F;
|
||||||
|
vy_ = 0.0F;
|
||||||
|
|
||||||
ax_ = 0.0F; // Aceleración en el eje X. Variación de la velocidad
|
// Resetea aceleración
|
||||||
ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad
|
ax_ = 0.0F;
|
||||||
|
ay_ = 0.0F;
|
||||||
|
|
||||||
flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
|
// Resetea flip
|
||||||
|
flip_ = SDL_FLIP_NONE;
|
||||||
|
|
||||||
SurfaceSprite::clear();
|
SurfaceSprite::clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,73 +10,68 @@ class Surface; // lines 8-8
|
|||||||
// Clase SMovingSprite. Añade movimiento y flip al sprite
|
// Clase SMovingSprite. Añade movimiento y flip al sprite
|
||||||
class SurfaceMovingSprite : public SurfaceSprite {
|
class SurfaceMovingSprite : public SurfaceSprite {
|
||||||
public:
|
public:
|
||||||
protected:
|
// Constructores
|
||||||
float x_; // Posición en el eje X
|
|
||||||
float y_; // Posición en el eje Y
|
|
||||||
|
|
||||||
float vx_ = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
|
|
||||||
float vy_ = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
|
|
||||||
|
|
||||||
float ax_ = 0.0F; // Aceleración en el eje X. Variación de la velocidad
|
|
||||||
float ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad
|
|
||||||
|
|
||||||
SDL_FlipMode flip_; // Indica como se voltea el sprite
|
|
||||||
|
|
||||||
// Mueve el sprite (time-based)
|
|
||||||
void move(float delta_time);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructor
|
|
||||||
SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip);
|
SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos, SDL_FlipMode flip);
|
||||||
SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos);
|
SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_FRect pos);
|
||||||
explicit SurfaceMovingSprite();
|
explicit SurfaceMovingSprite();
|
||||||
explicit SurfaceMovingSprite(std::shared_ptr<Surface> surface);
|
explicit SurfaceMovingSprite(std::shared_ptr<Surface> surface);
|
||||||
|
|
||||||
// Destructor
|
|
||||||
~SurfaceMovingSprite() override = default;
|
~SurfaceMovingSprite() override = default;
|
||||||
|
|
||||||
// Actualiza las variables internas del objeto (time-based)
|
// Actualización y renderizado
|
||||||
void update(float delta_time) override;
|
void update(float delta_time) override; // Actualiza variables internas (time-based)
|
||||||
|
void render() override; // Muestra el sprite por pantalla
|
||||||
|
void render(Uint8 source_color, Uint8 target_color) override; // Renderiza con reemplazo de color
|
||||||
|
|
||||||
// Reinicia todas las variables a cero
|
// Gestión de estado
|
||||||
void clear() override;
|
void clear() override; // Reinicia todas las variables a cero
|
||||||
|
|
||||||
// Muestra el sprite por pantalla
|
// Getters de posición
|
||||||
void render() override;
|
|
||||||
void render(Uint8 source_color, Uint8 target_color) override;
|
|
||||||
|
|
||||||
// Obtiene la variable
|
|
||||||
[[nodiscard]] auto getPosX() const -> float { return x_; }
|
[[nodiscard]] auto getPosX() const -> float { return x_; }
|
||||||
[[nodiscard]] auto getPosY() const -> float { return y_; }
|
[[nodiscard]] auto getPosY() const -> float { return y_; }
|
||||||
|
|
||||||
|
// Getters de velocidad
|
||||||
[[nodiscard]] auto getVelX() const -> float { return vx_; }
|
[[nodiscard]] auto getVelX() const -> float { return vx_; }
|
||||||
[[nodiscard]] auto getVelY() const -> float { return vy_; }
|
[[nodiscard]] auto getVelY() const -> float { return vy_; }
|
||||||
|
|
||||||
|
// Getters de aceleración
|
||||||
[[nodiscard]] auto getAccelX() const -> float { return ax_; }
|
[[nodiscard]] auto getAccelX() const -> float { return ax_; }
|
||||||
[[nodiscard]] auto getAccelY() const -> float { return ay_; }
|
[[nodiscard]] auto getAccelY() const -> float { return ay_; }
|
||||||
|
|
||||||
// Establece la variable
|
// Setters de posición
|
||||||
|
void setPos(SDL_FRect rect); // Establece posición y tamaño del objeto
|
||||||
|
void setPos(float x, float y); // Establece posición x, y
|
||||||
|
void setPosX(float value); // Establece posición X
|
||||||
|
void setPosY(float value); // Establece posición Y
|
||||||
|
|
||||||
|
// Setters de velocidad
|
||||||
void setVelX(float value) { vx_ = value; }
|
void setVelX(float value) { vx_ = value; }
|
||||||
void setVelY(float value) { vy_ = value; }
|
void setVelY(float value) { vy_ = value; }
|
||||||
|
|
||||||
|
// Setters de aceleración
|
||||||
void setAccelX(float value) { ax_ = value; }
|
void setAccelX(float value) { ax_ = value; }
|
||||||
void setAccelY(float value) { ay_ = value; }
|
void setAccelY(float value) { ay_ = value; }
|
||||||
|
|
||||||
// Establece el valor de la variable
|
// Gestión de flip (volteo horizontal)
|
||||||
void setFlip(SDL_FlipMode flip) { flip_ = flip; }
|
void setFlip(SDL_FlipMode flip) { flip_ = flip; } // Establece modo de flip
|
||||||
|
auto getFlip() -> SDL_FlipMode { return flip_; } // Obtiene modo de flip
|
||||||
|
void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; } // Alterna flip horizontal
|
||||||
|
|
||||||
// Gira el sprite horizontalmente
|
protected:
|
||||||
void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; }
|
// Métodos protegidos
|
||||||
|
void move(float delta_time); // Mueve el sprite (time-based)
|
||||||
|
|
||||||
// Obtiene el valor de la variable
|
// Variables miembro - Posición
|
||||||
auto getFlip() -> SDL_FlipMode { return flip_; }
|
float x_{0.0F}; // Posición en el eje X
|
||||||
|
float y_{0.0F}; // Posición en el eje Y
|
||||||
|
|
||||||
// Establece la posición y_ el tamaño del objeto
|
// Variables miembro - Velocidad (pixels/segundo)
|
||||||
void setPos(SDL_FRect rect);
|
float vx_{0.0F}; // Velocidad en el eje X
|
||||||
|
float vy_{0.0F}; // Velocidad en el eje Y
|
||||||
|
|
||||||
// Establece el valor de las variables
|
// Variables miembro - Aceleración (pixels/segundo²)
|
||||||
void setPos(float x, float y);
|
float ax_{0.0F}; // Aceleración en el eje X
|
||||||
|
float ay_{0.0F}; // Aceleración en el eje Y
|
||||||
|
|
||||||
// Establece el valor de la variable
|
// Variables miembro - Renderizado
|
||||||
void setPosX(float value);
|
SDL_FlipMode flip_{SDL_FLIP_NONE}; // Modo de volteo del sprite
|
||||||
|
|
||||||
// Establece el valor de la variable
|
|
||||||
void setPosY(float value);
|
|
||||||
};
|
};
|
||||||
@@ -45,8 +45,8 @@ void SurfaceSprite::setPosition(SDL_FPoint p) {
|
|||||||
|
|
||||||
// Reinicia las variables a cero
|
// Reinicia las variables a cero
|
||||||
void SurfaceSprite::clear() {
|
void SurfaceSprite::clear() {
|
||||||
pos_ = {0.0F, 0.0F, 0.0F, 0.0F};
|
pos_ = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
|
||||||
clip_ = {0.0F, 0.0F, 0.0F, 0.0F};
|
clip_ = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el estado del sprite (time-based)
|
// Actualiza el estado del sprite (time-based)
|
||||||
|
|||||||
Reference in New Issue
Block a user