Bläddra i källkod

added override.

Nicolas Cannasse 19 år sedan
förälder
incheckning
d9a5470560

+ 1 - 0
ast.ml

@@ -189,6 +189,7 @@ type access =
 	| APublic
 	| APublic
 	| APrivate
 	| APrivate
 	| AStatic
 	| AStatic
+	| AOverride
 
 
 type class_field =
 type class_field =
 	| FVar of string * documentation * access list * type_path option * expr option
 	| FVar of string * documentation * access list * type_path option * expr option

+ 3 - 1
parser.ml

@@ -276,7 +276,8 @@ and parse_class_field s =
 				f_expr = e;
 				f_expr = e;
 			} in
 			} in
 			(FFun (name,doc,l,pl,f),punion p1 (pos e))
 			(FFun (name,doc,l,pl,f),punion p1 (pos e))
-		| [< >] -> if l = [] then raise Stream.Failure else serror()
+		| [< >] ->
+			if l = [] && doc = None then raise Stream.Failure else serror()
 
 
 and parse_signature_field = parser
 and parse_signature_field = parser
 	| [< '(Kwd Var,p1); name = any_ident; s >] ->
 	| [< '(Kwd Var,p1); name = any_ident; s >] ->
@@ -290,6 +291,7 @@ and parse_cf_rights allow_static l = parser
 	| [< '(Kwd Static,_) when allow_static; l = parse_cf_rights false (AStatic :: l) >] -> l
 	| [< '(Kwd Static,_) when allow_static; l = parse_cf_rights false (AStatic :: l) >] -> l
 	| [< '(Kwd Public,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APublic :: l) >] -> l
 	| [< '(Kwd Public,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APublic :: l) >] -> l
 	| [< '(Kwd Private,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APrivate :: l) >] -> l
 	| [< '(Kwd Private,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APrivate :: l) >] -> l
+	| [< '(Const (Ident "override"),_) when allow_static; l = parse_cf_rights false (AOverride :: l) >] -> l
 	| [< >] -> l
 	| [< >] -> l
 
 
 and parse_fun_name = parser
 and parse_fun_name = parser

+ 3 - 3
std/haxe/remoting/AsyncDebugConnection.hx

@@ -35,7 +35,7 @@ class AsyncDebugConnection extends AsyncConnection, implements Dynamic<AsyncDebu
 		setErrorHandler(__error.ref);
 		setErrorHandler(__error.ref);
 	}
 	}
 
 
-	function setErrorHandler(f) {
+	override function setErrorHandler(f) {
 		var me = this;
 		var me = this;
 		__error.ref = function(e) {
 		__error.ref = function(e) {
 			var l = me.lastCalls.pop();
 			var l = me.lastCalls.pop();
@@ -46,7 +46,7 @@ class AsyncDebugConnection extends AsyncConnection, implements Dynamic<AsyncDebu
 		return f;
 		return f;
 	}
 	}
 
 
-	function __resolve(field : String) : AsyncConnection {
+	override function __resolve(field : String) : AsyncConnection {
 		var s = new AsyncDebugConnection(__data.__resolve(field));
 		var s = new AsyncDebugConnection(__data.__resolve(field));
 		s.lastCalls = lastCalls;
 		s.lastCalls = lastCalls;
 		s.__error = __error;
 		s.__error = __error;
@@ -69,7 +69,7 @@ class AsyncDebugConnection extends AsyncConnection, implements Dynamic<AsyncDebu
 		trace(path.join(".")+"("+params.join(",")+") = "+Std.string(result));
 		trace(path.join(".")+"("+params.join(",")+") = "+Std.string(result));
 	}
 	}
 
 
-	public function call( params : Array<Dynamic>, onData : Dynamic -> Void ) : Void {
+	override public function call( params : Array<Dynamic>, onData : Dynamic -> Void ) : Void {
 		lastCalls.add({ path : __data.__path, params : params });
 		lastCalls.add({ path : __data.__path, params : params });
 		onCall(__data.__path,params);
 		onCall(__data.__path,params);
 		var me = this;
 		var me = this;

+ 2 - 2
std/haxe/remoting/DelayedConnection.hx

@@ -33,7 +33,7 @@ class DelayedConnection extends AsyncConnection, implements Dynamic<DelayedConne
 
 
 	public var connection(getConnection,setConnection) : AsyncConnection;
 	public var connection(getConnection,setConnection) : AsyncConnection;
 
 
-	function __resolve( field : String ) : AsyncConnection {
+	override function __resolve( field : String ) : AsyncConnection {
 		var d = new DelayedConnection(__data,__path.copy());
 		var d = new DelayedConnection(__data,__path.copy());
 		d.__path.push(field);
 		d.__path.push(field);
 		return d;
 		return d;
@@ -51,7 +51,7 @@ class DelayedConnection extends AsyncConnection, implements Dynamic<DelayedConne
 		return cnx;
 		return cnx;
 	}
 	}
 
 
-	public function call( params, onData ) {
+	override public function call( params, onData ) {
 		var d : InternalData = __data;
 		var d : InternalData = __data;
 		d.msg.push({ path : __path, params : params, onData : onData });
 		d.msg.push({ path : __path, params : params, onData : onData });
 		process(d);
 		process(d);

+ 2 - 2
std/haxe/remoting/LocalConnection.hx

@@ -32,7 +32,7 @@ class LocalConnection extends AsyncConnection {
 
 
 	var __funs : List<Dynamic -> Void>;
 	var __funs : List<Dynamic -> Void>;
 
 
-	function __resolve(field) : AsyncConnection {
+	override function __resolve(field) : AsyncConnection {
 		var s = new LocalConnection(__data,__path.copy());
 		var s = new LocalConnection(__data,__path.copy());
 		s.__error = __error;
 		s.__error = __error;
 		s.__funs = __funs;
 		s.__funs = __funs;
@@ -40,7 +40,7 @@ class LocalConnection extends AsyncConnection {
 		return s;
 		return s;
 	}
 	}
 
 
-	public function call( params : Array<Dynamic>, onData : Dynamic -> Void ) : Void {
+	override public function call( params : Array<Dynamic>, onData : Dynamic -> Void ) : Void {
 		try {
 		try {
 			var s = new haxe.Serializer();
 			var s = new haxe.Serializer();
 			var p = __path.copy();
 			var p = __path.copy();

+ 2 - 2
std/haxe/remoting/SocketConnection.hx

@@ -31,7 +31,7 @@ class SocketConnection extends AsyncConnection {
 	var __r : Server;
 	var __r : Server;
 	#end
 	#end
 
 
-	function __resolve(field) : AsyncConnection {
+	override function __resolve(field) : AsyncConnection {
 		var s = new SocketConnection(__data,__path.copy());
 		var s = new SocketConnection(__data,__path.copy());
 		var me = this;
 		var me = this;
 		s.__error = __error;
 		s.__error = __error;
@@ -43,7 +43,7 @@ class SocketConnection extends AsyncConnection {
 		return s;
 		return s;
 	}
 	}
 
 
-	public function call( params : Array<Dynamic>, onData : Dynamic -> Void ) : Void {
+	override public function call( params : Array<Dynamic>, onData : Dynamic -> Void ) : Void {
 		try {
 		try {
 			var s = new haxe.Serializer();
 			var s = new haxe.Serializer();
 			s.serialize(true);
 			s.serialize(true);

+ 4 - 4
std/tools/haxedoc/Main.hx

@@ -290,12 +290,12 @@ private class DocClass {
 
 
 private class DocEnum extends DocClass {
 private class DocEnum extends DocClass {
 
 
-	function genName( s : StringBuf ) {
+	override function genName( s : StringBuf ) {
 		s.add("enum ");
 		s.add("enum ");
 		s.add(path);
 		s.add(path);
 	}
 	}
 
 
-	function genBody( s : StringBuf ) {
+	override function genBody( s : StringBuf ) {
 		for( f in fields ) {
 		for( f in fields ) {
 			s.add("<dt>");
 			s.add("<dt>");
 			s.add(f.name);
 			s.add(f.name);
@@ -314,7 +314,7 @@ private class DocSign extends DocClass {
 
 
 	public var t : DocType;
 	public var t : DocType;
 
 
-	function genBody( s : StringBuf ) {
+	override function genBody( s : StringBuf ) {
 		if( t == null ) {
 		if( t == null ) {
 			super.genBody(s);
 			super.genBody(s);
 			return;
 			return;
@@ -324,7 +324,7 @@ private class DocSign extends DocClass {
 		s.add("</dt>");
 		s.add("</dt>");
 	}
 	}
 
 
-	function genName( s : StringBuf ) {
+	override function genName( s : StringBuf ) {
 		s.add("signature ");
 		s.add("signature ");
 		s.add(path);
 		s.add(path);
 	}
 	}

+ 2 - 0
type.ml

@@ -115,6 +115,7 @@ and tclass = {
 	mutable cl_dynamic : t option;
 	mutable cl_dynamic : t option;
 	mutable cl_constructor : tclass_field option;
 	mutable cl_constructor : tclass_field option;
 	mutable cl_init : texpr option;
 	mutable cl_init : texpr option;
+	mutable cl_overrides : string list;
 }
 }
 
 
 and tenum_field = {
 and tenum_field = {
@@ -192,6 +193,7 @@ let mk_class path pos doc priv =
 		cl_dynamic = None;
 		cl_dynamic = None;
 		cl_constructor = None;
 		cl_constructor = None;
 		cl_init = None;
 		cl_init = None;
+		cl_overrides = [];
 	}
 	}
 
 
 let null_class = mk_class ([],"") Ast.null_pos None true
 let null_class = mk_class ([],"") Ast.null_pos None true

+ 22 - 14
typer.ml

@@ -1762,7 +1762,7 @@ let type_static_var ctx t e p =
 	unify ctx e.etype t p;
 	unify ctx e.etype t p;
 	e
 	e
 
 
-let check_overloading ctx c p () =
+let check_overriding ctx c p () =
 	match c.cl_super with
 	match c.cl_super with
 	| None -> ()
 	| None -> ()
 	| Some (csup,params) ->
 	| Some (csup,params) ->
@@ -1770,7 +1770,11 @@ let check_overloading ctx c p () =
 			try
 			try
 				let t , f2 = class_field csup i in
 				let t , f2 = class_field csup i in
 				let t = apply_params csup.cl_types params t in
 				let t = apply_params csup.cl_types params t in
-				if f.cf_public <> f2.cf_public then
+				ignore(follow f.cf_type); (* force evaluation *)
+				let p = (match f.cf_expr with None -> p | Some e -> e.epos) in
+				if not (List.mem i c.cl_overrides) then 
+					display_error ctx ("Field " ^ i ^ " should be declared with 'override' since it is inherited from superclass") p
+				else if f.cf_public <> f2.cf_public then
 					display_error ctx ("Field " ^ i ^ " has different visibility (public/private) than superclass one") p
 					display_error ctx ("Field " ^ i ^ " has different visibility (public/private) than superclass one") p
 				else if f2.cf_get <> f.cf_get || f2.cf_set <> f.cf_set then
 				else if f2.cf_get <> f.cf_get || f2.cf_set <> f.cf_set then
 					display_error ctx ("Field " ^ i ^ " has different property access than in superclass") p
 					display_error ctx ("Field " ^ i ^ " has different property access than in superclass") p
@@ -1784,6 +1788,8 @@ let rec check_interface ctx c p intf params =
 	PMap.iter (fun i f ->
 	PMap.iter (fun i f ->
 		try
 		try
 			let t , f2 = class_field c i in			
 			let t , f2 = class_field c i in			
+			ignore(follow f.cf_type); (* force evaluation *)
+			let p = (match f.cf_expr with None -> p | Some e -> e.epos) in
 			if f.cf_public && not f2.cf_public then
 			if f.cf_public && not f2.cf_public then
 				display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
 				display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
 			else if not(unify_access f2.cf_get f.cf_get) then
 			else if not(unify_access f2.cf_get f.cf_get) then
@@ -1865,7 +1871,7 @@ let init_class ctx c p herits fields =
 					cf.cf_type <- TLazy r;
 					cf.cf_type <- TLazy r;
 					(fun () -> ignore(!r()))
 					(fun () -> ignore(!r()))
 			) in
 			) in
-			List.mem AStatic access, false, cf, delay
+			access, false, cf, delay
 		| FFun (name,doc,access,params,f) ->
 		| FFun (name,doc,access,params,f) ->
 			let params = List.map (fun (n,flags) ->
 			let params = List.map (fun (n,flags) ->
 				match flags with
 				match flags with
@@ -1914,15 +1920,14 @@ let init_class ctx c p herits fields =
 					(fun() -> ignore((!r)()))
 					(fun() -> ignore((!r)()))
 				end
 				end
 			) in
 			) in
-			stat, constr, cf, delay
+			access, constr, cf, delay
 		| FProp (name,doc,access,get,set,t) ->
 		| FProp (name,doc,access,get,set,t) ->
-			let ret = load_type ctx p t in
-			let is_static = List.mem AStatic access in
+			let ret = load_type ctx p t in			
 			let check_get = ref (fun() -> ()) in
 			let check_get = ref (fun() -> ()) in
 			let check_set = ref (fun() -> ()) in
 			let check_set = ref (fun() -> ()) in
 			let check_method m t () =
 			let check_method m t () =
 				try
 				try
-					let t2 = (if is_static then (PMap.find m c.cl_statics).cf_type else fst (class_field c m)) in
+					let t2 = (if List.mem AStatic access then (PMap.find m c.cl_statics).cf_type else fst (class_field c m)) in
 					unify_raise ctx t2 t p;
 					unify_raise ctx t2 t p;
 				with
 				with
 					| Error (Unify l,_) -> raise (Error (Stack (Custom ("In method " ^ m ^ " required by property " ^ name),Unify l),p))
 					| Error (Unify l,_) -> raise (Error (Stack (Custom ("In method " ^ m ^ " required by property " ^ name),Unify l),p))
@@ -1955,20 +1960,23 @@ let init_class ctx c p herits fields =
 				cf_public = is_public access;
 				cf_public = is_public access;
 				cf_params = [];
 				cf_params = [];
 			} in
 			} in
-			is_static, false, cf, (fun() -> (!check_get)(); (!check_set)())
+			access, false, cf, (fun() -> (!check_get)(); (!check_set)())
 	in
 	in
 	let fl = List.map (fun (f,p) ->
 	let fl = List.map (fun (f,p) ->
-		let static , constr, f , delayed = loop_cf f p in
+		let access , constr, f , delayed = loop_cf f p in
+		let is_static = List.mem AStatic access in
 		if constr then begin
 		if constr then begin
 			if c.cl_constructor <> None then error "Duplicate constructor" p;
 			if c.cl_constructor <> None then error "Duplicate constructor" p;
 			c.cl_constructor <- Some f;
 			c.cl_constructor <- Some f;
-		end else if not static || f.cf_name <> "__init__" then begin
-			if PMap.mem f.cf_name (if static then c.cl_statics else c.cl_fields) then error ("Duplicate class field declaration : " ^ f.cf_name) p;
-			if static then begin
+		end else if not is_static || f.cf_name <> "__init__" then begin
+			if PMap.mem f.cf_name (if is_static then c.cl_statics else c.cl_fields) then error ("Duplicate class field declaration : " ^ f.cf_name) p;
+			if is_static then begin
 				c.cl_statics <- PMap.add f.cf_name f c.cl_statics;
 				c.cl_statics <- PMap.add f.cf_name f c.cl_statics;
 				c.cl_ordered_statics <- f :: c.cl_ordered_statics;
 				c.cl_ordered_statics <- f :: c.cl_ordered_statics;
-			end else
+			end else begin
 				c.cl_fields <- PMap.add f.cf_name f c.cl_fields;
 				c.cl_fields <- PMap.add f.cf_name f c.cl_fields;
+				if List.mem AOverride access then c.cl_overrides <- f.cf_name :: c.cl_overrides;
+			end;
 		end;
 		end;
 		delayed
 		delayed
 	) fields in
 	) fields in
@@ -2129,7 +2137,7 @@ let type_module ctx m tdecls loadp =
 			m.mimports <- (md,topt) :: m.mimports;			
 			m.mimports <- (md,topt) :: m.mimports;			
 		| EClass (name,_,_,herits,fields) ->
 		| EClass (name,_,_,herits,fields) ->
 			let c = get_class name in
 			let c = get_class name in
-			delays := !delays @ check_overloading ctx c p :: check_interfaces ctx c p :: init_class ctx c p herits fields
+			delays := !delays @ check_overriding ctx c p :: check_interfaces ctx c p :: init_class ctx c p herits fields
 		| EEnum (name,_,_,_,constrs) ->
 		| EEnum (name,_,_,_,constrs) ->
 			let e = get_enum name in
 			let e = get_enum name in
 			ctx.type_params <- e.e_types;
 			ctx.type_params <- e.e_types;