Quellcode durchsuchen

[cs] don't generate reflection setter for @:readOnly fields (closes #4598)

Aleksandr Kuzmenko vor 6 Jahren
Ursprung
Commit
ef6197849c

+ 7 - 4
src/codegen/gencommon/reflectionCFs.ml

@@ -989,10 +989,13 @@ let implement_get_set ctx cl =
 
 		let content =
 			let fields = get_fields() in
-			let fields = List.filter (fun (_, cf) -> match is_set, cf.cf_kind with
-				| true, Var { v_write = AccCall } -> true
-				| false, Var { v_read = AccCall } -> true
-				| _ -> Type.is_physical_field cf) fields
+			let fields = List.filter
+				(fun (_, cf) -> match is_set, cf.cf_kind with
+					| true, Var { v_write = AccCall } -> true
+					| false, Var { v_read = AccCall } -> true
+					| _ -> Type.is_physical_field cf && not (has_meta Meta.ReadOnly cf.cf_meta)
+				)
+				fields
 			in
 			(if fields <> [] then has_fields := true);
 			let cases = List.map (fun (names, cf) ->

+ 16 - 0
tests/misc/cs/projects/Issue4598/Main.hx

@@ -0,0 +1,16 @@
+class Main {
+	@:readOnly
+	public var a:Int = 10;
+
+	static function main() {
+		var m = new Main();
+
+		try Reflect.setProperty(m, 'a', 999)
+		catch(e:cs.system.MemberAccessException) {}
+		if(m.a != 10) {
+			throw "Main.a should not be writable via reflection";
+		}
+	}
+
+	public function new() {}
+}

+ 12 - 0
tests/misc/cs/projects/Issue4598/Run.hx

@@ -0,0 +1,12 @@
+class Run {
+	static public function run() {
+		var exe = 'bin/bin/Main.exe';
+		var exitCode = switch (Sys.systemName()) {
+			case 'Windows':
+				Sys.command(exe);
+			case _:
+				Sys.command('mono', [exe]);
+		}
+		Sys.exit(exitCode);
+	}
+}

+ 4 - 0
tests/misc/cs/projects/Issue4598/compile.hxml

@@ -0,0 +1,4 @@
+-cs bin
+-main Main
+--next
+--macro Run.run()