COMMUNITY

Modifying AST at compile time with Haxe 4.0?


(Alex Kotik) #1

Is it somehow possible to hook into the compilation process after all macro expanded and etc, traverse the AST and change some things inside it? Is there any way to write a compiler plugin that can do it? Or is it possible with Haxe’s powerful macro system?


(Alex Kotik) #2

I tried using onAfterTyping, but it seems that changing the class definition this way is not possible. It seems to be possible to exclude the class from compilation and redeclare the class by using defineType, but how to do I fix all of the links to the excluded classes in other classes methods? I tried addGlobalMetadata method and adding a build attribute to all classes, but in that way I can change class members and methods, but I can’t rename a class for example.

What I’m trying to do is an obfuscator/minifier for Haxe output. Particulalry I’m interested in minified JS output, obviously I could use external tool and run it over generated compiler output, but I think it may be possible for all targets, if I implement it using Haxe macros or something. But for what I’m seeing right now it seems to be impossible.


(Mark) #3

The same discussion is here:

I once tried obfuscating/name mangling myself once too, you might want to check out https://github.com/markknol/hxobfuscator The basic principle here is to append @:native to everything and give it a smaller name. I found it rather complex in some cases so its not fully working.

BTW There are already several tools for minifying js output:
http://lib.haxe.org/p/uglifyjs (using uglify.js, requires node)
http://lib.haxe.org/p/closure (using closure compiler, requires java)
https://github.com/YellowAfterlife/HaxMin (haxe, requires neko)


(Alex Kotik) #4

I tried applying your approach of adding “:native” metadata for all classes. It seems to work perfectly fine for JavaScript target, but when I try to apply it to CSharp target I get a lot of type not found errors. And I don’t really know why this happens (native metadata doesn’t remove types, at least what I’m thinking it doesn’t) and what to do with it. I’m applying the build metadata to all classes using “–macro addGlobalMetadata(’’, ‘@:build(Builder.build())’)”. Here is my Builder class code:

public static macro function build():Array<Field> {
    var fields = Context.getBuildFields();
    var aclass = Context.getLocalClass();

    if(aclass != null) {
        var nam = 'C{Builder._counter++}';
        var pos = Context.currentPos();
        var mac = [macro $v{nam}];

        aclass.get().meta.add(":native", mac, pos);
    }

    return fields;
}

public static function use() {
    Context.onTypeNotFound(function (name:String) {
        trace(name);
        return null;
    });
}

EDIT: To be fair, if I try applying the :native metadata to my classes only, everything seems to work fine. So the metadata only “undefines” internal hscs’s classes for whatever reason.