Lumberyard
Guía del usuario (Version 1.21)

Automatización de texto reutilizable con AZ Code Generator

La versión publicada de AZ Code Generator es preliminar y está sujeta a cambios.

AZ Code Generator es una utilidad de línea de comando que genera código fuente (o cualquier cantidad de datos o texto) desde código fuente con etiquetado especial. Puede utilizarlo cuando la estructura del dirigido código se conoce con antelación, de forma que las plantillas se puedan adaptar al mismo. Por ejemplo, puede generar un código reutilizable para la serialización o el reflejo.

AZ Code Generator analiza una lista de archivos fuente o archivos de encabezado en C++ existentes y genera datos intermedios en formato JSON. Pasa los datos intermedios a una serie de plantillas.

Las plantillas proporcionan el formato del código que se genera. Las plantillas posibilitan un aumento de la eficacia del código, ya que habilitan las actualizaciones automáticas del código reutilizable. Cuando una plantilla se actualiza, todo el código generado relacionado se regenera en la siguiente compilación. Esto elimina la necesidad de actualizar a mano el código de adherencia o de utilizar operaciones de búsqueda y reemplazo, que son propensas a causar errores.

Resumen del flujo de trabajo

En los siguientes pasos se describe cómo funciona AZ Code Generator con Waf para generar código.

  1. El sistema de compilación Waf invoca a AZ Code Generator para los archivos de origen .h y .cpp que se especifican en el archivo wscript.

  2. AZ Code Generator ejecuta uno o varios pases con los archivos especificados.

  3. Cada pase incluye lo siguiente:

    1. AZ Code Generator utiliza el compilador front-end Clang para producir un árbol de sintaxis abstracta (AST) para cada archivo de origen facilitado. El analizador Clang intenta compilar la entrada. Para mayor velocidad, se puede indicar a Clang que no siga declaraciones #include y que suprima todos los errores.

    2. El AST se traduce en un formato JSON intermedio.

    3. El objeto JSON intermedio se pasa a un controlador de plantilla como script Python y, posteriormente, a una plantilla Jinja2. Cada controlador y cada plantilla implementan tareas de generación de código específicas.

    4. El controlador de la plantilla realiza las tareas previas al procesamiento que quiera aplicar al objeto JSON intermedio.

    5. A continuación, el JSON intermedio se pasa a las plantillas Jinja2.

    6. Cada controlador de plantilla puede tener un número arbitrario de plantillas, que pueden crear un número arbitrario de archivos de salida. Varias plantillas pueden crear el mismo archivo de salida o archivos de salida diferentes, según quiera el creador del controlador de plantilla.

  4. AZ Code Generator devuelve una lista de los archivos generados al sistema de compilación Waf.

  5. El sistema de compilación Waf completa el proceso de compilación, incluido el código generado en la compilación.

En las secciones siguientes se proporcionan más detalles sobre este proceso.

Waf

AZ Code Generator está totalmente integrado en Con el sistema de compilación Waf Puede utilizar la característica az_code_gen de Waf para invocar al AZ Code Generator. Le recomendamos que utilice Waf en lugar de la línea de comando para iniciar la utilidad AzCodeGenerator.exe.

Para obtener ejemplos y más información acerca de la integración de Waf, consulte Integración de AZ Code Generator con Waf .

Clang

El front-end predeterminado de AZ Code Generator es un analizador/compilador Clang para código fuente C++. AZ Code Generator utiliza Clang para analizar código fuente (que podría incluir etiquetas personalizadas) y generar el objeto de datos JSON intermedio. AZ Code Generator controla totalmente la fase de análisis y compilación de Clang de modo que pueda suprimir o habilitar de manera selectiva algunas características, como las de diagnóstico. De este modo, AZ Code Generator tiene la flexibilidad necesaria para pasar por alto el código fuente que podría dejar de compilar y, aun así, tratar de generar un objeto intermedio completo.

Datos JSON intermedios

El compilador front-end Clang produce una estructura de datos JSON intermedios que el generador envía a las plantillas para que se sigan procesando. A continuación presentamos un ejemplo de un objeto de datos JSON intermedios.

[ { 'name' : 'Component', 'qualified_name' : 'AZ::Component', 'fields' : [], 'bases' : [], 'meta' : { 'path' : 'D:\\Repo\\Ly\\branches\\AzComponents\\Code\\Tools\\AzCodeGenerator\\CodeGenTest.h' }, 'type' : 'class', 'annotations' : {}, 'methods' : [] }, { 'name' : 'TestingClass', 'qualified_name' : 'TheNamespace::TestingClass', 'fields' : [ { 'type' : 'float', 'name' : 'm_field2', 'qualified_name' : 'TheNamespace::TestingClass::m_field2', 'annotations' : {} } ], 'bases' : [ { 'name' : 'Component', 'qualified_name' : 'AZ::Component' } ], 'meta' : { 'path' : 'D:\\Repo\\Ly\\branches\\AzComponents\\Code\\Tools\\AzCodeGenerator\\CodeGenTest.h' }, 'type' : 'class', 'annotations' : {}, 'methods' : [ { 'params' : ['type', 'int', 'name', 'version'], 'name' : 'CreateArgumentAnnotation', 'qualified_name' : 'TheNamespace::TestingClass::CreateArgumentAnnotation', 'annotations' : {} } ] } ]

Para ver la sintaxis completa del objeto de datos JSON intermedios, consulte Formato de datos JSON intermedio.

AZ Code Generator y Python

AZ Code Generator depende de Python 2.7 para ejecutar controladores de plantillas y crear plantillas de Jinja. La API de Python C se utiliza para ampliar Python con métodos en el módulo azcg_extension que permiten que los controladores de plantillas informen de dependencias, errores y salida de información útiles. En Windows, Python 2.7 está incluido en el directorio dev/Tools/Python de Lumberyard. En macOS, AZ Code Generator utiliza la versión de Python que se incluye con el sistema operativo.

nota

Para depurar las llamadas a la API de Python C al utilizar AZ Code Generator, debe descargar CPython. A continuación, realice una compilación para el sistema operativo de depuración de su elección.

Controladores de plantillas y representación de plantillas

Puede utilizar controladores de plantillas en Python para alterar la estructura de datos intermedios antes de pasarla al motor de la plantilla. Tras el procesamiento previo, el controlador de la plantilla podría indicar al motor de la plantilla Jinja2 que represente una o varias plantillas, en función del código generado que desee.

AZ Code Generator utiliza el motor de plantilla Jinja2, que descarga el script easy_install de Python en el directorio \dev\Tools\Python\2.7.11\windows\Scripts. A continuación, el motor se copia en el directorio 3rdParty\jinja2 de Lumberyard. Lumberyard también proporciona un módulo jinja_extensions que contiene métodos de ayudante que puede usar en las plantillas. Estas extensiones se almacenan en el directorio dev/Code/Tools/AzCodeGenerator/Scripts/jinja_extensions/. Para obtener ejemplos y más información sobre las plantillas Jinja, consulte Plantillas de generación de código.

Archivos generados

El siguiente resultado de muestra se generó desde una plantilla de serialización. El objeto JSON de referencia ha sido formateado para facilitar su legibilidad.

///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// // THIS CODE IS AUTOGENERATED, DO NOT MODIFY ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// #include "stdafx.h" #include <AZCore/Rtti/ReflectContext.h> #include <AzCore/Rtti/Rtti.h> #include <AzCore/Serialization/SerializeContext.h> #include <AzCore/Math/Vector3.h> #include "D:/Repo/Ly/branches/AzComponents/Code/Tools/AzCodeGenerator/CodeGenTest.h" namespace Components { void TestingClassReflect(AZ::ReflectContext* reflection) { AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection); if (serializeContext) { serializeContext->Class<TestingClass>() ->SerializerForEmptyClass() ; } } } /////////////////////////////////////////////////////////////// /* // Reference JSON object [{ 'name':'Component', 'qualified_name':'AZ::Component', 'fields':[ ], 'bases':[ ], 'meta':{ 'path':'D:\\Repo\\Ly\\branches\\AzComponents\\Code\\Tools\\AzCodeGenerator\\CodeGenTest.h' }, 'type':'class', 'annotations':{ }, 'methods':[ ] }, { 'name':'TestingClass', 'qualified_name':'TheNamespace::TestingClass', 'fields':[ { 'type':'float', 'name':'m_field2', 'qualified_name':'TheNamespace::TestingClass::m_field2', 'annotations':{ } } ], 'bases':[ { 'name':'Component', 'qualified_name':'AZ::Component' } ], 'meta':{ 'path':'D:\\Repo\\Ly\\branches\\AzComponents\\Code\\Tools\\AzCodeGenerator\\CodeGenTest.h' }, 'type':'class', 'annotations':{ }, 'methods':[ { 'params':[ 'type', 'int', 'name', 'version' ], 'name':'CreateArgumentAnnotation', 'qualified_name':'TheNamespace::TestingClass::CreateArgumentAnnotation', 'annotations':{ } } ] }] */