types - utiliza - manual macros en excel 2010 pdf
En Haxe, ¿cómo se agregan Tipos/Clases a un Módulo con macros? (2)
Me gustaría agregar dinámicamente algunos tipos nuevos a un módulo dado en función de algunos archivos encontrados en un directorio.
Básicamente estoy tratando de poblar un montón de clases @:file(...)
incrustadas en la parte inferior de un Módulo.
//This is the module I''m targeting to append embedded ByteArray subtypes (see below)
@:build(macros.AutoEmbed.build("some/folder/"))
class Embeds {
//Empty on purpose, just let the Macro do its thing!
}
// At "macro-time", it should generate these:
@:file("some/folder/ui_main.xml")
class UI_MAIN_XML extends flash.utils.ByteArray { }
@:file("some/folder/config.template.json")
class CONFIG_TEMPLATE_JSON extends flash.utils.ByteArray { }
Lo que he podido encontrar hasta ahora es que podría tener que modificar el módulo de Embeds.hx
. Así que busqué en Context.getModule( Context.getLocalModule() )
. También busqué en TypeDefinition
ya que parece ser la única forma de definir un nuevo tipo desde cero.
El problema con Context.getModule(...)
es que devuelve una matriz Array<Type>
, no Array<TypeDefinition>
, por lo que no puedo TypeDefinition
nueva TypeDefinition
(además tengo que descubrir cómo escribir esos , ughh ). Esa es probablemente una mala suposición de mi parte, pero pensé que simplemente añadiendo más TypeDefinition
podría proporcionar dinámicamente más tipos en el módulo.
¡Todavía soy muy nuevo en Macros como puedes ver!
EDITAR
Es cierto que podría escribir / sobreescribir dinámicamente un nuevo archivo Embeds.hx
en tiempo de compilación con una solución de escritura FileSystem / File , pero eso implica la necesidad de compilar al menos una vez antes de que la autocompletación de IDE pueda recoger las Embeds.*
generadas Embeds.*
clases (FlashDevelop en mi caso). Además, cada vez que se eliminan nuevos archivos en la carpeta definida, se produce el mismo problema: primero debe compilar antes de que el IDE lo detecte. Sí, realmente me gusta la autocompletación :)
Comenzar desde la macro de construcción es bueno. Puede construir campos de clase y crear tipos.
Aquí hay una macro que solo generará un tipo y un campo correspondiente:
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
class AutoEmbed
{
macro static public function build(folder:String):Array<Field>
{
var inClass = Context.getLocalClass().get();
// explore folder and create those:
var fileName = ''resource/strings.json'';
var name = fileName.split(''/'').pop().split(''.'').join(''_'');
var valueExpr = makeType(inClass.pack, name, fileName);
var field = {
name: name,
access: [APublic, AStatic, AInline],
kind: FVar(null, valueExpr),
pos: Context.currentPos()
}
return [field];
}
static function makeType(pack:Array<String>, name:String, fileName:String)
{
var pos = Context.currentPos();
var className = name.toUpperCase();
var cdef = macro class Tmp extends haxe.io.BytesData { }
cdef.pack = pack.copy();
cdef.name = className;
cdef.meta = [{
name: '':file'',
params: [Context.makeExpr(fileName, pos)],
pos: pos
}];
haxe.macro.Context.defineType(cdef);
return {
expr:EConst(CIdent(className)),
pos:pos
};
}
}
#end
Ahora para usarlo:
trace(Embed.strings_json); // [ByteArray]
@:build(AutoEmbed.build(''some/folder''))
class Embeds
{
// generate field strings_json pointing to class STRINGS_JSON
}
Puede usar la macro de inicialización: http://haxe.org/manual/macro-initialization.html para ejecutar macro antes de escribir.
Luego, para crear realmente nuevas clases / módulos, puede usar Context.defineModule: http://api.haxe.org/haxe/macro/Context.html#defineModule