Browse Source

fix precedence between assignment and metadata (closes #4121)

Simon Krajewski 9 years ago
parent
commit
8933061e3e

+ 3 - 4
parser.ml

@@ -141,15 +141,14 @@ let rec make_unop op ((v,p2) as e) p1 =
 	match v with
 	| EBinop (bop,e,e2) -> EBinop (bop, make_unop op e p1 , e2) , (punion p1 p2)
 	| ETernary (e1,e2,e3) -> ETernary (make_unop op e1 p1 , e2, e3), punion p1 p2
-	| _ ->
-		EUnop (op,Prefix,e), punion p1 p2
+	| _ -> EUnop (op,Prefix,e), punion p1 p2
 
 let rec make_meta name params ((v,p2) as e) p1 =
 	match v with
+	| EBinop ((OpAssign | OpAssignOp _),_,_) -> EMeta((name,params,p1),e),punion p1 p2
 	| EBinop (bop,e,e2) -> EBinop (bop, make_meta name params e p1 , e2) , (punion p1 p2)
 	| ETernary (e1,e2,e3) -> ETernary (make_meta name params e1 p1 , e2, e3), punion p1 p2
-	| _ ->
-		EMeta((name,params,p1),e),punion p1 p2
+	| _ -> EMeta((name,params,p1),e),punion p1 p2
 
 let make_is e t p =
 	let e_is = EField((EConst(Ident "Std"),p),"is"),p in

+ 10 - 0
tests/unit/src/unit/issues/Issue4121.hx

@@ -0,0 +1,10 @@
+package unit.issues;
+
+import unit.issues.misc.Issue4121Macro.wrap;
+
+class Issue4121 extends Test {
+	function test() {
+		eq("(@:test ((x) = (1)))", wrap(@:test x = 1));
+		eq("(@:test (@:test2 ((x) = (@:test3 (1)))))", wrap(@:test @:test2 x = @:test3 1));
+	}
+}

+ 14 - 0
tests/unit/src/unit/issues/misc/Issue4121Macro.hx

@@ -0,0 +1,14 @@
+package unit.issues.misc;
+
+import haxe.macro.Expr;
+using haxe.macro.Tools;
+
+class Issue4121Macro {
+	macro static public function wrap(e:Expr) {
+		function addParens(e:Expr) {
+			return macro (${e.map(addParens)});
+		}
+		var e = addParens(e);
+		return macro $v{e.toString()};
+	}
+}