daily pastebin goal
41%
SHARE
TWEET

Untitled

a guest Jan 11th, 2019 57 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package ftk.tools;
  2.  
  3. #if macro
  4. import haxe.macro.Context;
  5. import haxe.macro.Type;
  6. import haxe.macro.Expr;
  7. #else
  8. import ftk.db.Object;
  9. #end
  10.  
  11. /**
  12.  * ...
  13.  * @author
  14.  */
  15.  
  16. enum EProp {
  17.     ESimple( prop : String );
  18.     EComplex( prop : String, props : Array<EProp> );
  19. }
  20.  
  21. class SerializeHelper {
  22. #if !macro
  23.     public static inline function with<T:Object>( o : T, props : Array<EProp> ) : T {
  24.         for ( eprop in props ){
  25.             switch( eprop ){
  26.                 case ESimple( prop )            :
  27.                     if ( o.xfields.indexOf( prop ) == -1 ){
  28.                         o.xfields.push( prop );
  29.                     }
  30.                 case EComplex( prop, props )    :
  31.                     if ( o.xfields.indexOf( prop ) == -1 ){
  32.                         o.xfields.push( prop );
  33.                     }
  34.                     var v   : Dynamic = Reflect.getProperty( o, prop );
  35.                     if ( Std.is( v, Array ) ){
  36.                         SerializeIterableHelper.with( (v:Array<T>), props );
  37.                     }else if ( Std.is( v, List ) ){
  38.                         SerializeIterableHelper.with( (v:List<T>), props );
  39.                     }else {
  40.                         SerializeHelper.with( (v:T), props );
  41.                     }
  42.             }
  43.         }
  44.         return o;
  45.     }
  46. #end
  47. }
  48.  
  49. class SerializeIterableHelper {
  50. #if !macro
  51.     public static inline function with<T:Object>( it : Iterable<T>, props : Array<EProp> ) : Iterable<T>{
  52.         for ( o in it ){
  53.             SerializeHelper.with( o , props );
  54.         }
  55.         return it;
  56.     }
  57. #end
  58. }
  59.  
  60. class MacroSerializeHelper{
  61.     @:access( ftk.tools._MacroSerializeHelper.processWithCall )
  62.     public static macro function mwith( expr : ExprOf<Object>, properties : Array<Expr> ) : Expr {
  63.         return _MacroSerializeHelper.processWithCall( expr, properties );
  64.     }
  65. }
  66.  
  67. class MacroSerializeIterableHelper{
  68.     @:access( ftk.tools._MacroSerializeHelper.processWithCall )
  69.     public static macro function mwith( expr : ExprOf<Iterable<Object>>, properties : Array<Expr> ) : Expr {
  70.         return _MacroSerializeHelper.processWithCall( expr, properties );
  71.     }
  72. }
  73.  
  74. class _MacroSerializeHelper {
  75.    
  76. #if macro
  77.  
  78.     static function processWithCall( obj:Expr, properties:Array<Expr> ):Expr {
  79.         var lines = process( obj, obj, properties, [macro var __obj = $obj] );
  80.         lines.push( macro __obj );
  81.         return macro @:pos(obj.pos) $b{lines};
  82.     }
  83.    
  84.     static function processObjects( iterable:Expr, typedIterable:Expr, properties:Array<Expr>, blockExpressions:Array<Expr> ):Array<Expr> {
  85.         var ident = macro __obj;
  86.         var typeExpr = macro $typedIterable.iterator().next();
  87.         var lines = processObject( ident, typeExpr, properties, [] );
  88.         var block = macro $b{lines};
  89.         var loopExpr = macro for ($ident in $iterable) $block;
  90.         blockExpressions.push( loopExpr );
  91.         return blockExpressions;
  92.     }
  93.    
  94.     static function processObject( obj:Expr, typedExpr:Expr, properties:Array<Expr>, blockExpressions:Array<Expr> ):Array<Expr> {
  95.         var fields = macro @:pos(obj.pos) $obj.xfields;
  96.         function addField( propertyName:String ) {
  97.             var expr = macro if ($fields.indexOf($v{propertyName})==-1) $fields.push( $v{propertyName} );
  98.             var getterCall = macro $obj.$propertyName;
  99.             blockExpressions.push( getterCall );
  100.             blockExpressions.push( expr );
  101.         }
  102.         function removeField( propertyName:String ) {
  103.             var expr = macro while ($fields.indexOf($v{propertyName})>-1) $fields.remove( $v{propertyName} );
  104.             blockExpressions.push( expr );
  105.         }
  106.         for ( p in properties ) {
  107.             switch p {
  108.                 case macro []:
  109.                     blockExpressions.push( macro $fields = [] );
  110.                 case macro $i{propertyName}:
  111.                     Context.typeof( macro @:pos(obj.pos) $typedExpr.$propertyName );
  112.                     addField( propertyName );
  113.                 case macro -$i{propertyName}:
  114.                     Context.typeof( macro @:pos(obj.pos) $typedExpr.$propertyName );
  115.                     removeField( propertyName );
  116.                 case macro $i{propertyName}=>$a{subProperties}:
  117.                     var property = macro @:pos(obj.pos) $obj.$propertyName;
  118.                     var typedProperty = macro @:pos(obj.pos) $typedExpr.$propertyName;
  119.                     addField( propertyName );
  120.                     process( property, typedProperty, subProperties, blockExpressions );
  121.                 case _:
  122.                     Context.fatalError( 'Could not understand property name ${ Std.string( p ) }', Context.currentPos() );
  123.             }
  124.         }
  125.         return blockExpressions;
  126.     }
  127.    
  128.     static function process( expr:Expr, typedProp:Expr, properties:Array<Expr>, blockExpressions:Array<Expr> ):Array<Expr> {
  129.         var exprType = Context.typeof( typedProp );
  130.         var objectType = Context.typeof( macro new ftk.db.Object() );
  131.         var iterableType = Context.typeof( macro { var it : Iterable<ftk.db.Object> = null; it; } );
  132.  
  133.         if ( Context.unify(exprType, objectType) ) {
  134.             return processObject( expr, typedProp, properties, blockExpressions );
  135.         }
  136.         else if ( Context.unify(exprType,iterableType) ) {
  137.             return processObjects( expr, typedProp, properties, blockExpressions );
  138.         }
  139.         else {
  140.             Context.fatalError( '${ Std.string( expr ) } is not a ftk.db.Object nor Iterable of', Context.currentPos() );
  141.             return null;
  142.         }
  143.     }
  144. #end
  145. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top