2
0
Эх сурвалжийг харах

prevent handling formated string when passed to a macro (fixed issue #1284)

Nicolas Cannasse 12 жил өмнө
parent
commit
2cb50b8911
2 өөрчлөгдсөн 34 нэмэгдсэн , 7 устгасан
  1. 27 6
      lexer.mll
  2. 7 1
      typer.ml

+ 27 - 6
lexer.mll

@@ -96,17 +96,37 @@ let newline lexbuf =
 	cur.lline <- cur.lline + 1;
 	cur.llines <- (lexeme_end lexbuf,cur.lline) :: cur.llines
 
-let add_fmt_string pmin =
+let fmt_pos p =
+	p.pmin + (p.pmax - p.pmin) * 1000000
+
+let add_fmt_string p =
+	let file = (try
+		Hashtbl.find all_files p.pfile
+	with Not_found ->
+		let f = make_file p.pfile in
+		Hashtbl.replace all_files p.pfile f;
+		f
+	) in
+	file.lstrings <- (fmt_pos p) :: file.lstrings
+
+let fast_add_fmt_string p =
 	let cur = !cur in
-	cur.lstrings <- pmin :: cur.lstrings
+	cur.lstrings <- (fmt_pos p) :: cur.lstrings
 	
 let is_fmt_string p =
 	try
 		let file = Hashtbl.find all_files p.pfile in
-		List.mem p.pmin file.lstrings
+		List.mem (fmt_pos p) file.lstrings
 	with Not_found ->
 		false
-	
+
+let remove_fmt_string p =
+	try
+		let file = Hashtbl.find all_files p.pfile in
+		file.lstrings <- List.filter ((<>) (fmt_pos p)) file.lstrings
+	with Not_found ->
+		()
+
 let find_line p f =
 	(* rebuild cache if we have a new line *)
 	if f.lmaxline <> f.lline then begin
@@ -258,8 +278,9 @@ and token = parse
 			let pmin = lexeme_start lexbuf in
 			let pmax = (try string2 lexbuf with Exit -> error Unterminated_string pmin) in
 			let str = (try unescape (contents()) with Exit -> error Invalid_escape pmin) in
-			add_fmt_string pmin;
-			mk_tok (Const (String str)) pmin pmax;
+			let t = mk_tok (Const (String str)) pmin pmax in
+			fast_add_fmt_string (snd t);
+			t
 		}
 	| "~/" {
 			reset();

+ 7 - 1
typer.ml

@@ -3197,6 +3197,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 		| _ ->
 			el,[]
 	in
+	let todo = ref [] in
 	let args =
 		(*
 			force default parameter types to haxe.macro.Expr, and if success allow to pass any value type since it will be encoded
@@ -3210,7 +3211,11 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 		let constants = List.map (fun e ->
 			let p = snd e in
 			let e = (try
-				ignore(Codegen.type_constant_value ctx.com e);
+				(match Codegen.type_constant_value ctx.com e with
+				| { eexpr = TConst (TString _); epos = p } when Lexer.is_fmt_string p ->
+					Lexer.remove_fmt_string p;
+					todo := (fun() -> Lexer.add_fmt_string p) :: !todo;
+				| _ -> ());
 				e
 			with Error (Custom _,_) ->
 				(* if it's not a constant, let's make something that is typed as haxe.macro.Expr - for nice error reporting *)
@@ -3224,6 +3229,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			(EArray ((EArrayDecl [e],p),(EConst (Int (string_of_int (!index))),p)),p)
 		) el in
 		let elt, _ = unify_call_params ctx2 (Some (TInst(mclass,[]),mfield)) constants (List.map fst eargs) t_dynamic p false in
+		List.iter (fun f -> f()) (!todo);
 		List.map2 (fun (_,ise) e ->
 			let e, et = (match e.eexpr with
 				(* get back our index and real expression *)