Created
March 22, 2016 20:52
-
-
Save Simn/9c60e152212c32d0dc43 to your computer and use it in GitHub Desktop.
Simple assert macro that shows sub-expressions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Main { | |
static function main() { | |
var x = 7; | |
var y = 10; | |
tools.Assert.assert(x == 7 && y == 11); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
src/Main.hx:5: characters 22-39 : Assertion failure: x == 7 && y == 11 | |
src/Main.hx:5: characters 22-39 : x: 7 | |
src/Main.hx:5: characters 22-39 : x == 7: true | |
src/Main.hx:5: characters 22-39 : y: 10 | |
src/Main.hx:5: characters 22-39 : y == 11: false | |
src/Main.hx:5: characters 22-39 : x == 7 && y == 11: false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tools; | |
import haxe.macro.Expr; | |
using haxe.macro.Tools; | |
class Assert { | |
static public macro function assert(e:Expr) { | |
var s = e.toString(); | |
var p = e.pos; | |
var el = []; | |
var descs = []; | |
function add(e:Expr, s:String) { | |
var v = "_tmp" + el.length; | |
el.push(macro var $v = $e); | |
descs.push(s); | |
return v; | |
} | |
function map(e:Expr) { | |
return switch (e.expr) { | |
case EConst((CInt(_) | CFloat(_) | CString(_) | CRegexp(_) | CIdent("true" | "false" | "null"))): | |
e; | |
case _: | |
var s = e.toString(); | |
e = e.map(map); | |
macro $i{add(e, s)}; | |
} | |
} | |
var e = map(e); | |
var a = [for (i in 0...el.length) macro { expr: $v{descs[i]}, value: $i{"_tmp" + i} }]; | |
el.push(macro if (!$e) @:pos(p) throw new tools.Assert.AssertionFailure($v{s}, $a{a})); | |
el.push(e); | |
return macro $b{el}; | |
} | |
} | |
private typedef AssertionPart = { | |
expr: String, | |
value: Dynamic | |
} | |
class AssertionFailure { | |
public var message(default, null):String; | |
public var parts(default, null):Array<AssertionPart>; | |
public function new(message:String, parts:Array<AssertionPart>) { | |
this.message = message; | |
this.parts = parts; | |
} | |
public function toString() { | |
var buf = new StringBuf(); | |
buf.add("Assertion failure: " + message); | |
for (part in parts) { | |
buf.add("\n\t" + part.expr + ": " + part.value); | |
} | |
return buf.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment