primer commit

This commit is contained in:
2025-11-23 11:44:31 +01:00
commit 6ada29eaf8
613 changed files with 484459 additions and 0 deletions

View 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
```

View 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
```

View 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