Browse Source

Better error messages for property-related syntax errors

Closes #11280
Rudy Ges 1 year ago
parent
commit
0972725149

+ 5 - 0
src/syntax/grammar.mly

@@ -963,6 +963,9 @@ and parse_class_field tdecl s =
 		| [< '(Kwd Final,p1) >] ->
 		| [< '(Kwd Final,p1) >] ->
 			check_redundant_var p1 s;
 			check_redundant_var p1 s;
 			begin match s with parser
 			begin match s with parser
+			| [< opt,name = questionable_dollar_ident; '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_); t = popt parse_type_hint; e,p2 = parse_var_field_assignment >] ->
+				let meta = check_optional opt name in
+				name,punion p1 p2,FProp(i1,i2,t,e),(al @ [AFinal,p1]),meta
 			| [< opt,name = questionable_dollar_ident; t = popt parse_type_hint; e,p2 = parse_var_field_assignment >] ->
 			| [< opt,name = questionable_dollar_ident; t = popt parse_type_hint; e,p2 = parse_var_field_assignment >] ->
 				let meta = check_optional opt name in
 				let meta = check_optional opt name in
 				name,punion p1 p2,FVar(t,e),(al @ [AFinal,p1]),meta
 				name,punion p1 p2,FVar(t,e),(al @ [AFinal,p1]),meta
@@ -1235,6 +1238,8 @@ and parse_array_decl p1 s =
 and parse_var_decl_head final s =
 and parse_var_decl_head final s =
 	let meta = parse_meta s in
 	let meta = parse_meta s in
 	match s with parser
 	match s with parser
+	| [< name, p = dollar_ident; '(POpen,p1); _ = property_ident; '(Comma,_); _ = property_ident; '(PClose,p2); t = popt parse_type_hint >] ->
+		syntax_error (Custom "Cannot define property accessors for local vars") ~pos:(Some (punion p1 p2)) s (meta,name,final,t,p)
 	| [< name, p = dollar_ident; t = popt parse_type_hint >] -> (meta,name,final,t,p)
 	| [< name, p = dollar_ident; t = popt parse_type_hint >] -> (meta,name,final,t,p)
 	| [< >] ->
 	| [< >] ->
 		(* This nonsense is here for the var @ case in issue #9639 *)
 		(* This nonsense is here for the var @ case in issue #9639 *)

+ 5 - 1
src/typing/typeloadFields.ml

@@ -106,6 +106,9 @@ module FieldError = struct
 	let invalid_modifier_only com fctx m c p =
 	let invalid_modifier_only com fctx m c p =
 		maybe_display_error com fctx (Printf.sprintf "Invalid modifier: %s is only supported %s" m c) p
 		maybe_display_error com fctx (Printf.sprintf "Invalid modifier: %s is only supported %s" m c) p
 
 
+	let invalid_modifier_on_property com fctx m p =
+		maybe_display_error com fctx (Printf.sprintf "Invalid modifier: %s is not supported on properties" m) p
+
 	let missing_expression com fctx reason p =
 	let missing_expression com fctx reason p =
 		maybe_display_error com fctx (Printf.sprintf "%s" reason) p
 		maybe_display_error com fctx (Printf.sprintf "%s" reason) p
 
 
@@ -1631,9 +1634,10 @@ let init_field (ctx,cctx,fctx) f =
 	if not (has_class_flag c CExtern) && not (Meta.has Meta.Native f.cff_meta) then Typecore.check_field_name ctx name p;
 	if not (has_class_flag c CExtern) && not (Meta.has Meta.Native f.cff_meta) then Typecore.check_field_name ctx name p;
 	List.iter (fun acc ->
 	List.iter (fun acc ->
 		match (fst acc, f.cff_kind) with
 		match (fst acc, f.cff_kind) with
-		| APublic, _ | APrivate, _ | AStatic, _ | AFinal, _ | AExtern, _ -> ()
+		| APublic, _ | APrivate, _ | AStatic, _ | AFinal, FVar _ | AFinal, FFun _ | AExtern, _ -> ()
 		| ADynamic, FFun _ | AOverride, FFun _ | AMacro, FFun _ | AInline, FFun _ | AInline, FVar _ | AAbstract, FFun _ | AOverload, FFun _ -> ()
 		| ADynamic, FFun _ | AOverride, FFun _ | AMacro, FFun _ | AInline, FFun _ | AInline, FVar _ | AAbstract, FFun _ | AOverload, FFun _ -> ()
 		| AEnum, (FVar _ | FProp _) -> ()
 		| AEnum, (FVar _ | FProp _) -> ()
+		| AFinal, FProp _ -> invalid_modifier_on_property ctx.com fctx (Ast.s_placed_access acc) (snd acc)
 		| _, FVar _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for variable " ^ name) (snd acc)
 		| _, FVar _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for variable " ^ name) (snd acc)
 		| _, FProp _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for property " ^ name) (snd acc)
 		| _, FProp _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for property " ^ name) (snd acc)
 		| _, FFun _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for function " ^ name) (snd acc)
 		| _, FFun _ -> display_error ctx.com ("Invalid accessor '" ^ Ast.s_placed_access acc ^ "' for function " ^ name) (snd acc)

+ 3 - 0
tests/misc/Issue11280/Main.hx

@@ -0,0 +1,3 @@
+function main() {
+	var foo(get, never):Int;
+}

+ 6 - 0
tests/misc/Issue11280/Main2.hx

@@ -0,0 +1,6 @@
+class Main {
+	public final bar(get, never):Int;
+	function get_bar():Int return 42;
+
+	static function main() {}
+}

+ 3 - 0
tests/misc/Issue11280/compile-fail.hxml

@@ -0,0 +1,3 @@
+-main Main
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/Issue11280/compile-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main.hx:2: characters 9-21
+
+ 2 |  var foo(get, never):Int;
+   |         ^^^^^^^^^^^^
+   | Cannot define property accessors for local vars
+

+ 3 - 0
tests/misc/Issue11280/compile2-fail.hxml

@@ -0,0 +1,3 @@
+-main Main2
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/Issue11280/compile2-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main2.hx:2: characters 9-14
+
+ 2 |  public final bar(get, never):Int;
+   |         ^^^^^
+   | Invalid modifier: final is not supported on properties
+