Browse Source

[js] Syntax.plainCode (fixes #9081)

Aleksandr Kuzmenko 5 years ago
parent
commit
9c26689191

+ 9 - 2
src/generators/genjs.ml

@@ -374,7 +374,7 @@ let print_deprecation_message com msg p =
 let is_code_injection_function e =
 	match e.eexpr with
 	| TIdent "__js__"
-	| TField (_, FStatic ({ cl_path = ["js"],"Syntax" }, { cf_name = "code" }))
+	| TField (_, FStatic ({ cl_path = ["js"],"Syntax" }, { cf_name = "code" | "plainCode" }))
 		-> true
 	| _ ->
 		false
@@ -966,7 +966,7 @@ and gen_syntax ctx meth args pos =
 		let code, code_pos =
 			match code.eexpr with
 			| TConst (TString s) -> s, code.epos
-			| _ -> abort "The `code` argument for js.Syntax must be a string constant" code.epos
+			| _ -> abort "The `code` argument for js.Syntax.code must be a string constant" code.epos
 		in
 		begin
 			match args with
@@ -988,6 +988,13 @@ and gen_syntax ctx meth args pos =
 				in
 				Codegen.interpolate_code ctx.com code args (spr ctx) (gen_value ctx) code_pos
 		end
+	| "plainCode", [code] ->
+		let code =
+			match code.eexpr with
+			| TConst (TString s) -> s
+			| _ -> abort "The `code` argument for js.Syntax.plainCode must be a string constant" code.epos
+		in
+		spr ctx (String.concat "\n" (ExtString.String.nsplit code "\r\n"))
 	| "field" , [eobj;efield] ->
 		gen_value ctx eobj;
 		(match Texpr.skip efield with

+ 5 - 2
std/haxe/macro/Compiler.hx

@@ -486,8 +486,11 @@ class Compiler {
 
 				var f = try sys.io.File.getContent(Context.resolvePath(file)) catch (e:Dynamic) Context.error(Std.string(e), Context.currentPos());
 				var p = Context.currentPos();
-				var magic = if (Context.defined("js")) "__js__" else "__lua__";
-				{expr: EUntyped({expr: ECall({expr: EConst(CIdent(magic)), pos: p}, [{expr: EConst(CString(f)), pos: p}]), pos: p}), pos: p};
+				if(Context.defined("js")) {
+					macro @:pos(p) js.Syntax.plainCode($v{f});
+				} else {
+					macro @:pos(p) untyped __lua__($v{f});
+				}
 			case Top | Closure:
 				@:privateAccess Context.includeFile(file, position);
 				macro {};

+ 8 - 0
std/js/Syntax.hx

@@ -43,9 +43,17 @@ extern class Syntax {
 		```haxe
 		console.log("hi", 42);
 		```
+
+		Emits a compilation error if the count of `args` does not match the count of placeholders in `code`.
 	**/
 	static function code(code:String, args:Rest<Dynamic>):Dynamic;
 
+	/**
+		Inject `code` directly into generated source.
+		The same as `js.Syntax.code` except this one does not provide code interpolation.
+	**/
+	static function plainCode(code:String):Dynamic;
+
 	/**
 		Generate `new cl(...args)` expression.
 	**/

+ 7 - 0
tests/unit/src/unit/TestSyntaxModule.hx

@@ -48,6 +48,13 @@ class TestSyntaxModule extends Test {
 	}
 	#end
 #end
+
+#if js
+	function testPlainCode() {
+		var s = Syntax.plainCode('"{0}"');
+		eq('{0}', s);
+	}
+#end
 }
 
 private class Construct {