Как создать макрос для расширений свойств

Я хотел бы написать свой собственный макрос для создания свойств, таких как объекты в Haxe. Этот вопрос касается не столько свойств, сколько написания макросов. (вероятно, в NME уже есть макрос для этого).

наличие этого класса в haxe

class Foo {
    @:property var bar:String;
}

Мне нравится, когда это расширяется до

class Foo {
    private var bar:String;

    public function setBar(_val:String):void {
        this.bar = _val;
    }

    public function getBar():String {
        return this.bar;
    }
 }

Я читал соответствующие документы, но, честно говоря, я нахожу их очень запутанными.

спасибо


person robkuz    schedule 02.01.2013    source источник


Ответы (2)


Вы можете посмотреть, как tinkerbell решает ту же проблему: https://github.com/back2dos/tinkerbell/wiki/tink_lang#wiki-accessors

person Franco Ponticelli    schedule 02.01.2013
comment
Привет, Франко, я просмотрел это - увы, это довольно запутанно. Я также посмотрел github.com/back2dos /tinkerbell/blob/master/src/tink/lang/macros/, но он делает так много вещей, что на самом деле не отвечает на более простые вопросы, которые у меня есть. например, почему все классы Tinkerbell реализуют tink.lang.Cls или как система макросов реагирует на @:xxx? почему это запускает макросистему? Также какова связь между @:prop и классом PropBuilder. Я не мог найти никакой информации об этом - person robkuz; 03.01.2013

Этот пример построителя типов (вставлен ниже для справки, но по ссылке есть более подробное описание) ), найденный в Руководстве по Haxe, является хорошим простым примером добавления функции в класс.

Добавление свойства было бы почти таким же. Я добавил цикл трассировки (поля), чтобы понять, как они определены:

Main.hx

@:build(TypeBuildingMacro.build("myFunc"))
class Main {
  static public function main() {
    trace(Main.myFunc); // my default
  }
}

TypeBuildingMacro.hx

import haxe.macro.Context;
import haxe.macro.Expr;

class TypeBuildingMacro {
  macro static public function build(fieldName:String):Array<Field> {
    var fields = Context.getBuildFields();
    for (field in fields) { trace(field); }
    var newField = {
      name: fieldName,
      doc: null,
      meta: [],
      access: [AStatic, APublic],
      kind: FVar(macro : String, macro "my default"),
      pos: Context.currentPos()
    };
    fields.push(newField);
    return fields;
  }
}

Обратите внимание, что Main.hx должен вызывать макрос с метаданными @:build, чтобы компилятор знал, что нужно запустить макрос (который добавляет функцию) перед обработкой самого класса Main.

person Jeff Ward    schedule 17.03.2016