HaxeFlixel/flixel

View on GitHub
flixel/system/macros/FlxMacroUtil.hx

Summary

Maintainability
Test Coverage
package flixel.system.macros;

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

using haxe.macro.Tools;

class FlxMacroUtil
{
    /**
     * Builds a map from static uppercase inline variables in an abstract type.
     *
     * @param    invert    Use the field value as the key and the name as the value
     */
    public static macro function buildMap(typePath:String, invert:Bool = false, ?exclude:Array<String>):Expr
    {
        var type = Context.getType(typePath);
        var values = [];

        if (exclude == null)
            exclude = ["NONE"];

        switch (type.follow())
        {
            case TAbstract(_.get() => ab, _):
                for (f in ab.impl.get().statics.get())
                {
                    switch (f.kind)
                    {
                        case FVar(AccInline, _):
                            var value = 0;
                            switch (f.expr().expr)
                            {
                                case TCast(Context.getTypedExpr(_) => expr, _):
                                    value = expr.getValue();
                                default:
                            }
                            if (f.name.toUpperCase() == f.name && exclude.indexOf(f.name) == -1) // uppercase?
                            {
                                values.push({name: f.name, value: value});
                            }
                        default:
                    }
                }
            default:
        }

        var finalExpr;
        if (invert)
            finalExpr = values.map(function(v) return macro $v{v.value} => $v{v.name});
        else
            finalExpr = values.map(function(v) return macro $v{v.name} => $v{v.value});

        return macro $a{finalExpr};
    }
    
    public static macro function deprecateOverride(fieldName:String, ?msg:String):Array<Field>
    {
        var fields = Context.getBuildFields();
        var pos:Position = null;
        for (field in fields)
        {
            if (field.name == fieldName)
            {
                pos = field.pos;
                break;
            }
        }
        
        if (pos != null)
        {
            if (msg == null)
                msg = '$fieldName is deprecated';
            
            Context.warning(msg, pos);
        }
        return null;
    }
}