Directrices de estilo de código

Cuando contribuyas al código fuente de Godot, se espera que sigas las pautas de estilo descritas a continuación. Algunas de ellas son verificadas a través del proceso de Integración Continua, y los revisores te pedirán que corrijas posibles problemas. Por lo tanto, es recomendable configurar tu sistema de la manera que se describe a continuación para asegurarte de que todos tus commits cumplan con las pautas.

C++ y Objective-C

No existen pautas escritas, pero el estilo de código acordado por los desarrolladores se aplica mediante el embellecedor de código clang-format, que se encarga automáticamente de todas nuestras convenciones. Algunas de ellas son las siguientes:

  • La indentación y alineación están basadas en tabulaciones (respectivamente una y dos tabulaciones)

  • Un espacio alrededor de operadores matemáticos y de asignación, así como después de comas

  • Los operadores de puntero y referencia se colocan después del identificador de la variable, no después del nombre del tipo

  • Más adelante, se darán más detalles sobre las inclusiones de encabezados

Las reglas utilizadas por clang-format se detallan en el archivo .clang-format del repositorio de Godot.

Mientras te asegures de que tu estilo coincida con el código circundante y de que no introduzcas espacios en blanco finales o sangrías basadas en espacios, deberías estar bien. Sin embargo, si planeas contribuir de forma regular, te recomendamos encarecidamente que configures clang-format localmente para verificar y corregir automáticamente todos tus commits.

Advertencia

El estilo de código de Godot no debe aplicarse al código de terceros, es decir, aquel que se incluye en el árbol de código fuente de Godot pero que no fue escrito específicamente para nuestro proyecto. Este código generalmente proviene de diferentes proyectos upstream con sus propias guías de estilo (o la falta de ellas), y no queremos introducir diferencias que dificulten la sincronización con los repositorios upstream.

El código de terceros generalmente se incluye en la carpeta thirdparty/ y, por lo tanto, puede excluirse fácilmente de los scripts de formato. Para los casos raros en los que sea necesario incluir directamente un fragmento de código de terceros dentro de un archivo de Godot, se puede utilizar /* clang-format off */ y /* clang-format on */ para indicarle a clang-format que ignore esa parte del código. De esta manera, el código de terceros mantendrá su estilo original y no se verá afectado por las reglas de formato de Godot.

Ver también

Estas pautas solo abarcan el formato del código. Consulta Directrices de uso para C++ para obtener una lista de características del lenguaje que están permitidas en las solicitudes de extracción (pull requests).

Usando clang-format localmente

Primero que nada, necesitarás instalar clang-format. En este momento, necesitas usar clang-format 13 para que sea compatible con el formato de Godot. Versiones posteriores podrían ser adecuadas, pero versiones anteriores podrían no admitir todas las opciones utilizadas o formatear algunas cosas de manera diferente, lo que podría provocar problemas de estilo en las solicitudes de extracción.

Instalación

Aquí te mostramos cómo instalar clang-format:

  • Linux: Por lo general, clang-format estará disponible de forma predeterminada con el conjunto de herramientas de clang que viene empaquetado en tu distribución. Si la versión de tu distribución no es la requerida, puedes descargar una versión precompilada desde el sitio web de LLVM, o si estás en una distribución derivada de Debian, puedes utilizar los repositorios upstream.

  • macOS y Windows: Puedes descargar binarios precompilados desde el sitio web de LLVM. Es posible que necesites agregar la ruta de la carpeta del binario a la variable de entorno PATH de tu sistema para poder llamar a clang-format directamente.

A continuación, tienes diferentes opciones para aplicar clang-format a tus cambios:

Uso manual

Puedes aplicar clang-format manualmente a uno o varios archivos con el siguiente comando:

clang-format -i <path/to/file(s)>
  • Exacto, -i indica que los cambios deben escribirse directamente en el archivo (por defecto, clang-format solo mostraría la versión corregida en la terminal).

  • El camino puede apuntar a varios archivos, ya sea uno tras otro o usando caracteres comodín como en una típica terminal Unix. Ten cuidado al usar globbing para no ejecutar clang-format en objetos compilados (archivos .o y .a) que se encuentren en el árbol de Godot. Es mejor usar core/*.{cpp,h} en lugar de core/*.

Gancho Pre-commit

Para facilitar su uso, proporcionamos un "pre-commit hook" para Git que ejecutará automáticamente clang-format en todos sus commits para verificarlos, y le permitirá aplicar sus cambios en el commit final.

Este "hook" es un script que se puede encontrar en misc/hooks, consulta el archivo README.md de esa carpeta para obtener las instrucciones de instalación.

Si tu clang-format no está en la variable PATH, es posible que tengas que editar el archivo pre-commit-clang-format para indicar la ruta correcta del binario para que funcione correctamente. Este "hook" fue probado en Linux y macOS, pero también debería funcionar en Git Shell en Windows.

Complemento IDE

La mayoría de los IDEs o editores de código tienen complementos de embellecimiento que se pueden configurar para ejecutar clang-format automáticamente, por ejemplo, cada vez que guardas un archivo.

Aquí tienes una lista no exhaustiva de complementos de embellecimiento para algunos IDEs:

(Las solicitudes de extracción son bienvenidas para ampliar esta lista con complementos probados.)

Incluciones de encabezado

Cuando se agreguen nuevos archivos de C++ o Objective-C o se incluyan nuevos encabezados en los archivos existentes, se deben seguir las siguientes reglas:

  • Las primeras líneas del archivo deben ser el encabezado de derechos de autor y la licencia MIT de Godot, copiados y pegados desde otro archivo. Asegúrate de ajustar el nombre del archivo.

  • En un archivo de encabezado .h, se deben utilizar protecciones de inclusión (include guards) con la forma NOMBREARCHIVO_H.

  • En un archivo .cpp (por ejemplo, filename.cpp), la primera inclusión debería ser aquella donde se declara la clase (por ejemplo, #include "filename.h"), seguido de una línea en blanco para separación.

  • A continuación, deben aparecer los encabezados del propio código base de Godot, incluidos en orden alfabético (aplicado por clang-format) con rutas relativas a la carpeta raíz. Esas inclusiones deben realizarse con comillas, por ejemplo, #include "core/object.h". Después del bloque de inclusiones de encabezados de Godot, debe haber una línea en blanco para separación.

  • Finalmente, los encabezados de terceros (ya sea de la carpeta thirdparty o de las rutas de inclusión del sistema) deben venir a continuación y deben incluirse con los símbolos < y >, por ejemplo, #include <png.h>. El bloque de inclusiones de encabezados de terceros también debe estar seguido por una línea en blanco para separación.

  • Los encabezados de Godot y de terceros deben incluirse en el archivo que los requiere, es decir, en el archivo .h si se utilizan en el código declarativo o en el archivo .cpp si se utilizan solo en el código imperativo.

Ejemplo:

/*************************************************************************/
/*  my_new_file.h                                                        */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#ifndef MY_NEW_FILE_H
#define MY_NEW_FILE_H

#include "core/hash_map.h"
#include "core/list.h"
#include "scene/gui/control.h"

#include <png.h>

...

#endif // MY_NEW_FILE_H
/*************************************************************************/
/*  my_new_file.cpp                                                      */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "my_new_file.h"

#include "core/math/math_funcs.h"
#include "scene/gui/line_edit.h"

#include <zlib.h>
#include <zstd.h>

Java

El código Java de Godot (principalmente en platform/android) también se aplica a través de clang-format, así que consulta las instrucciones anteriores para configurarlo. Ten en cuenta que esta guía de estilo solo se aplica al código escrito y mantenido por Godot, no al código de terceros, como la subcarpeta java/src/com/google.

Python

El sistema de construcción SCons de Godot está escrito en Python, y varios scripts incluidos en el árbol de código fuente también utilizan Python.

Para estos scripts y el sistema de construcción SCons de Godot, seguimos la guía de estilo de Black. Utiliza Black para formatear automáticamente tus cambios en Python.

Usando black localmente

Primero que nada, necesitarás instalar black. Black requiere Python 3.6.0 o superior para funcionar.

Instalación

He aquí cómo instalar negro:

pip3 install black --user

Luego, tienes diferentes posibilidades para aplicar Black a tus cambios:

Uso manual

Puedes aplicar black manualmente a uno o más archivos con el siguiente comando:

black -l 120 <path/to/file(s)>
  • -l 120 significa que el número permitido de caracteres por línea es 120. Este número fue acordado por los desarrolladores.

  • La ruta puede apuntar a varios archivos, ya sea uno tras otro o usando comodines como en una típica terminal Unix.

Gancho Pre-commit

Para facilitar el uso, proporcionamos un "pre-commit hook" para Git que ejecutará black automáticamente en todos tus commits para verificarlos y te permitirá aplicar sus cambios en el commit final.

Este "hook" es un script que se puede encontrar en misc/hooks. Consulta el archivo README.md de esa carpeta para obtener instrucciones de instalación.

Integración del editor

Muchos IDEs o editores de código tienen complementos de formateo que se pueden configurar para ejecutar black automáticamente, por ejemplo, cada vez que guardas un archivo. Para más detalles, puedes consultar Integración de Black con editores.

Guía de estilo para comentarios

Esta guía de estilo de comentarios se aplica a todos los lenguajes de programación utilizados dentro del código base de Godot.

  • Comienza los comentarios con un espacio para distinguirlos del código deshabilitado.

  • Usa mayúscula inicial en los comentarios (sentence case). Comienza los comentarios con un carácter en mayúscula y siempre termínalos con un punto.

  • Haz referencia a los nombres de variables y funciones, así como a los valores, utilizando comillas invertidas (backticks).

  • Agrupa los comentarios en aproximadamente 100 caracteres.

  • Puedes usar TODO:, FIXME:, NOTE:, o HACK: como advertencias cuando sea necesario.

Ejemplo:

// Compute the first 10,000 decimals of Pi.
// FIXME: Don't crash when computing the 1,337th decimal due to `increment`
//        being negative.

No repitas lo que el código ya dice en un comentario. Explica el por qué en lugar del cómo.

Mal:

// Draw loading screen.
draw_load_screen();

Puedes usar comentarios con estilo Javadoc encima de definiciones de funciones o macros. Se recomienda usar comentarios con estilo Javadoc únicamente para métodos que no están expuestos a la secuencia de comandos (scripting). Esto se debe a que los métodos expuestos deben documentarse en la referencia de clase XML en su lugar.

Ejemplo:

/**
 * Returns the number of nodes in the universe.
 * This can potentially be a very large number, hence the 64-bit return type.
 */
uint64_t Universe::get_node_count() {
    // ...
}

Para variables miembro, no uses comentarios con estilo Javadoc, en su lugar, utiliza comentarios de una sola línea:

class Universe {
    // The cached number of nodes in the universe.
    // This value may not always be up-to-date with the current number of nodes
    // in the universe.
    uint64_t node_count_cached = 0;
};