2016-07-15 57 views
1

假設您有類型構建宏,接口調用@:autoBuild使用上述宏,實現接口和類的擴展類。如果類不包含特定的方法,則宏將失敗。檢查構建宏是否已經處理祖先節點

像這樣:

Macro.hx

package; 

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

class Macro 
{ 
    macro public function build():Array<Field> 
    { 
     var fields = Context.getBuildFields(); 

     for (field in fields) { 
      if (field.name == "hello") { 
       //Do some modifications 

       return fields;  
      } 
     } 

     Context.error('${Context.getLocalClass().toString()} doesn\'t contain a method `hello`', Context.currentPos()); 

     return null; 
    } 
} 

I.hx

package; 

@:autoBuild(Macro.build()) 
interface I {} 

Foobar.hx

package; 

class Foobar implements I 
{ 
    public function new() {} 

    public function hello(person:String) 
    { 
     return 'Hello $person!'; 
    } 
} 

Foo.hx

package; 

@:keep 
class Foo extends Foobar {} 

正如你所看到的,我們檢查,如果場 「你好」 的存在。但是,Context.getBuildFields僅包含當前類別的字段,並且構建將失敗Foo

這是我的想法來的地方:爲什麼不檢查是否已經處理了任何祖先?我們將改變Macro.hx,以反映這一點:

Macro.hx

package; 

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

class Macro 
{ 
    macro public function build():Array<Field> 
    { 
     var c = Context.getLocalClass().get(); 
     if(isAncestorAlreadyProcessed(c)) { 
      return null; 
     } 

     var fields = Context.getBuildFields(); 

     for (field in fields) { 
      if (field.name == "hello") { 
       //Do some modifications 

       c.meta.add(":processed", [], c.pos); 

       return fields;  
      } 
     }  

     Context.error('${Context.getLocalClass().toString()} doesn\'t contain a method `hello`', Context.currentPos()); 

     return null; 
    } 

    private static function isAncestorAlreadyProcessed(c:ClassType) 
    { 
     if (c.meta.has(":processed")) return true; 
     if (c.superClass == null) return false; 

     return isAncestorAlreadyProcessed(c.superClass.t.get()); 
    } 
} 

而對於主要問題:我誤會haXe的宏類型的建築?有沒有更可行的方法來完成這項工作?我的代碼在特定場景中是否失敗?這個代碼是否有任何有害的副作用?

庫實現這樣的想法:https://github.com/Misiur/MacroAncestry

我試圖解決this問題。

回答

1

不,這是要走的路,使用元數據來存儲您處理的類的信息。 https://groups.google.com/forum/#!searchin/haxelang/francis $ 20bourre/haxelang/WEZ6_47rgqo/7NQXfUzUFQAJ

另一種方式,如果你沒有在運行時需要這些信息,是使用靜態數組上的專用類。 https://github.com/DoclerLabs/hexAnnotation/blob/master/src/hex/annotation/AnnotationReader.hx

你甚至可以推後,在你的編譯代碼這樣的信息: https://github.com/DoclerLabs/hexInject/blob/master/src/hex/di/annotation/AnnotationReader.hx

希望有所幫助。

+0

只有在haxe社區,一個答案,但具體解決我的問題。謝謝! – Misiur