Parcourir la source

[parser] make `final` in structures use class notation

Simon Krajewski il y a 7 ans
Parent
commit
470bbb2d54
2 fichiers modifiés avec 13 ajouts et 8 suppressions
  1. 6 7
      src/syntax/grammar.mly
  2. 7 1
      src/typing/typeload.ml

+ 6 - 7
src/syntax/grammar.mly

@@ -389,11 +389,11 @@ and parse_complex_type_inner = parser
 	| [< '(POpen,p1); t = parse_complex_type; '(PClose,p2) >] -> CTParent t,punion p1 p2
 	| [< '(BrOpen,p1); s >] ->
 		(match s with parser
-		| [< l,p2 = parse_type_anonymous false false >] -> CTAnonymous l,punion p1 p2
+		| [< l,p2 = parse_type_anonymous false >] -> CTAnonymous l,punion p1 p2
 		| [< t = parse_structural_extension; s>] ->
 			let tl = t :: plist parse_structural_extension s in
 			(match s with parser
-			| [< l,p2 = parse_type_anonymous false false >] -> CTExtend (tl,l),punion p1 p2
+			| [< l,p2 = parse_type_anonymous false >] -> CTExtend (tl,l),punion p1 p2
 			| [< l,p2 = parse_class_fields true p1 >] -> CTExtend (tl,l),punion p1 p2)
 		| [< l,p2 = parse_class_fields true p1 >] -> CTAnonymous l,punion p1 p2
 		| [< >] -> serror())
@@ -467,9 +467,8 @@ and parse_complex_type_next (t : type_hint) = parser
 			CTFunction ([t] , (t2,p2)),punion (pos t) p2)
 	| [< >] -> t
 
-and parse_type_anonymous opt final = parser
-	| [< '(Question,_) when not opt; s >] -> parse_type_anonymous true final s
-	| [< '(Kwd Final,_) when not opt && not final; s >] -> parse_type_anonymous opt true s
+and parse_type_anonymous opt = parser
+	| [< '(Question,_) when not opt; s >] -> parse_type_anonymous true s
 	| [< name, p1 = ident; t = parse_type_hint_with_pos; s >] ->
 		let p2 = pos (last_token s) in
 		let next acc =
@@ -478,7 +477,7 @@ and parse_type_anonymous opt final = parser
 				cff_meta = if opt then [Meta.Optional,[],null_pos] else [];
 				cff_access = [];
 				cff_doc = None;
-				cff_kind = if final then FProp(("default",null_pos),("never",null_pos),Some t,None) else FVar (Some t,None);
+				cff_kind = FVar (Some t,None);
 				cff_pos = punion p1 p2;
 			} :: acc
 		in
@@ -487,7 +486,7 @@ and parse_type_anonymous opt final = parser
 		| [< '(Comma,p2) >] ->
 			(match s with parser
 			| [< '(BrClose,p2) >] -> next [],p2
-			| [< l,p2 = parse_type_anonymous false false >] -> next l,punion p1 p2
+			| [< l,p2 = parse_type_anonymous false >] -> next l,punion p1 p2
 			| [< >] -> serror());
 		| [< >] -> serror()
 

+ 7 - 1
src/typing/typeload.ml

@@ -615,14 +615,20 @@ and load_complex_type ctx allow_display p (t,pn) =
 			let pub = ref true in
 			let dyn = ref false in
 			let params = ref [] in
+			let final = ref false in
 			List.iter (fun a ->
 				match a with
 				| APublic -> ()
 				| APrivate -> pub := false;
 				| ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true
-				| AStatic | AOverride | AInline | ADynamic | AMacro | AFinal -> error ("Invalid access " ^ Ast.s_access a) p
+				| AFinal -> final := true
+				| AStatic | AOverride | AInline | ADynamic | AMacro -> error ("Invalid access " ^ Ast.s_access a) p
 			) f.cff_access;
 			let t , access = (match f.cff_kind with
+				| FVar(t,e) when !final ->
+					no_expr e;
+					let t = (match t with None -> error "Type required for structure property" p | Some t -> t) in
+					load_complex_type ctx allow_display p t, Var { v_read = AccNormal; v_write = AccNever }
 				| FVar (Some (CTPath({tpackage=[];tname="Void"}),_), _)  | FProp (_,_,Some (CTPath({tpackage=[];tname="Void"}),_),_) ->
 					error "Fields of type Void are not allowed in structures" p
 				| FVar (t, e) ->