Переглянути джерело

Merge branch 'development' of github.com:HaxeFoundation/haxe into development

Nicolas Cannasse 11 роки тому
батько
коміт
4dcd4f098c
4 змінених файлів з 38 додано та 84 видалено
  1. 13 11
      genjs.ml
  2. 0 70
      std/haxe/macro/Build.hx
  3. 0 2
      typeload.ml
  4. 25 1
      typer.ml

+ 13 - 11
genjs.ml

@@ -517,7 +517,7 @@ and gen_expr ctx e =
 	| TBlock el ->
 		print ctx "{";
 		let bend = open_block ctx in
-		List.iter (gen_block ctx) el;
+		List.iter (gen_block_element ctx) el;
 		bend();
 		newline ctx;
 		print ctx "}";
@@ -611,7 +611,7 @@ and gen_expr ctx e =
 		let bend = open_block ctx in
 		newline ctx;
 		print ctx "var %s = %s.next()" (ident v.v_name) it;
-		gen_block ctx e;
+		gen_block_element ctx e;
 		bend();
 		newline ctx;
 		spr ctx "}";
@@ -651,7 +651,7 @@ and gen_expr ctx e =
 					newline ctx;
 					print ctx "var %s = %s" v.v_name vname;
 				end;
-				gen_block ctx e;
+				gen_block_element ctx e;
 				if !else_block then begin
 					newline ctx;
 					print ctx "}";
@@ -666,7 +666,7 @@ and gen_expr ctx e =
 					newline ctx;
 					print ctx "var %s = %s" v.v_name vname;
 				end;
-				gen_block ctx e;
+				gen_block_element ctx e;
 				bend();
 				newline ctx;
 				spr ctx "} else ";
@@ -693,7 +693,7 @@ and gen_expr ctx e =
 					spr ctx ":"
 			) el;
 			let bend = open_block ctx in
-			gen_block ctx e2;
+			gen_block_element ctx e2;
 			if not (has_return e2) then begin
 				newline ctx;
 				print ctx "break";
@@ -706,7 +706,7 @@ and gen_expr ctx e =
 		| Some e ->
 			spr ctx "default:";
 			let bend = open_block ctx in
-			gen_block ctx e;
+			gen_block_element ctx e;
 			bend();
 			newline ctx;
 		);
@@ -721,17 +721,19 @@ and gen_expr ctx e =
 		spr ctx ")"
 
 
-and gen_block ?(after=false) ctx e =
+and gen_block_element ?(after=false) ctx e =
 	match e.eexpr with
 	| TBlock el ->
-		List.iter (gen_block ~after ctx) el
+		List.iter (gen_block_element ~after ctx) el
 	| TCall ({ eexpr = TLocal { v_name = "__feature__" } }, { eexpr = TConst (TString f) } :: eif :: eelse) ->
 		if has_feature ctx f then
-			gen_block ~after ctx eif
+			gen_block_element ~after ctx eif
 		else (match eelse with
 			| [] -> ()
-			| [e] -> gen_block ~after ctx e
+			| [e] -> gen_block_element ~after ctx e
 			| _ -> assert false)
+	| TFunction _ ->
+		gen_block_element ~after ctx (mk (TParenthesis e) e.etype e.epos)
 	| _ ->
 		if not after then newline ctx;
 		gen_expr ctx e;
@@ -1250,7 +1252,7 @@ let generate com =
 		print ctx "function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; o.hx__closures__[m.__id__] = f; } return f; }";
 		newline ctx;
 	end;
-	List.iter (gen_block ~after:true ctx) (List.rev ctx.inits);
+	List.iter (gen_block_element ~after:true ctx) (List.rev ctx.inits);
 	List.iter (generate_static ctx) (List.rev ctx.statics);
 	(match com.main with
 	| None -> ()

+ 0 - 70
std/haxe/macro/Build.hx

@@ -63,74 +63,4 @@ class Build {
 		}
 		return fields;
 	}
-
-	macro static public function exposeUnderlyingFields(fieldExprs:Array<Expr>):Array<Field> {
-		var fields = Context.getBuildFields();
-		var a = switch(Context.getLocalClass().get().kind) {
-			case KAbstractImpl(a): a;
-			case _: throw "";
-		}
-		var tThis = a.get().type;
-		var map:Type->Type = function(t) return t;
-		var c = switch(tThis.follow()) {
-			case TInst(c, tl):
-				var c = c.get();
-				if (tl.length > 0) map = function(t) {
-					var t2 = t.applyTypeParameters(c.params, tl);
-					return t2;
-				}
-				c;
-			case _: Context.error("Underlying type of exposing abstract must be a class", Context.currentPos());
-		}
-		function getIdentNames(e) return switch(e.expr) {
-			case EConst(CIdent(s)): { field : s, newField : s };
-			case EBinop(OpArrow, { expr : EConst(CIdent(s1))}, { expr: EConst(CIdent(s2))}): { field: s1, newField : s2 };
-			case _: Context.error("Identifier or (Identifier => Identifier) expected", e.pos);
-		}
-		function toField(cf:ClassField, oldName:String, newName:String) {
-			return {
-				name: newName,
-				doc: cf.doc,
-				access: [AStatic, APublic, AInline],
-				pos: cf.pos,
-				meta: [{name: ":impl", params: [], pos: cf.pos}],
-				kind: switch(cf.type.follow()) {
-					case TFun(args, ret):
-						var args = args.map(function(arg) return {
-							name: arg.name,
-							opt: arg.opt,
-							type: arg.t.toComplexType(),
-							value: null
-						});
-						var expr = macro return this.$oldName($a{args.map(function(arg) return macro $i{arg.name})});
-						args.unshift({name: "this", type: null, opt:false, value: null});
-						FFun({
-							args: args,
-							ret: ret.toComplexType(),
-							expr: expr,
-							params: cf.params.map(function(param) return {
-								name: param.name,
-								constraints: [],
-								params: []
-							})
-						});
-					case _: throw "";
-				}
-			}
-		}
-		for (fieldExpr in fieldExprs) {
-			var fieldNames = getIdentNames(fieldExpr);
-			var fieldName = fieldNames.field;
-			var cField = c.findField(fieldName, false);
-			if (cField == null) Context.error('Underlying type has no field $fieldName', fieldExpr.pos);
-			switch(cField.kind) {
-				case FMethod(_):
-				case _: Context.error("Only function fields can be exposed", fieldExpr.pos);
-			}
-			cField.type = map(cField.type);
-			var field = toField(cField, fieldName, fieldNames.newField);
-			fields.push(field);
-		}
-		return fields;
-	}
 }

+ 0 - 2
typeload.ml

@@ -196,8 +196,6 @@ let make_module ctx mpath file tdecls loadp =
 							c.cl_meta <- m :: c.cl_meta;
 						| (Meta.Enum,_,_) ->
 							c.cl_meta <- (Meta.Build,[ECall((EField((EField((EField((EConst(Ident "haxe"),p),"macro"),p),"Build"),p),"buildEnumAbstract"),p),[]),p],p) :: c.cl_meta;
-						| (Meta.Forward,el,_) ->
-							c.cl_meta <- (Meta.Build,[ECall((EField((EField((EField((EConst(Ident "haxe"),p),"macro"),p),"Build"),p),"exposeUnderlyingFields"),p),el),p],p) :: c.cl_meta;
 						| _ ->
 							()
 					) a.a_meta;

+ 25 - 1
typer.ml

@@ -871,6 +871,7 @@ let field_access ctx mode f fmode t e p =
 			| MethMacro, MCall -> AKMacro (e,f)
 			| _ , MGet ->
 				let cmode = (match fmode with
+					| FInstance(_, cf) | FStatic(_, cf) when Meta.has Meta.Generic cf.cf_meta -> display_error ctx "Cannot create closure on generic function" p; fmode
 					| FInstance (c,cf) -> FClosure (Some c,cf)
 					| FStatic _ | FEnum _ -> fmode
 					| FAnon f -> FClosure (None, f)
@@ -1296,6 +1297,13 @@ and type_field ?(resume=false) ctx e i p mode =
 				AKUsing (ef,c,f,e)
 			| MSet, _ ->
 				error "This operation is unsupported" p)
+		with Not_found -> try
+			let _,el,_ = Meta.get Meta.Forward a.a_meta in
+			if not (List.exists (fun e -> match fst e with
+				| EConst(Ident s | String s) -> s = i
+				| _ -> error "Identifier or string expected as argument to @:forward" (pos e)
+			) el) && el <> [] then raise Not_found;
+			type_field ctx {e with etype = apply_params a.a_types pl a.a_this} i p mode;
 		with Not_found -> try
 			using_field ctx mode e i p
 		with Not_found -> try
@@ -3089,6 +3097,22 @@ and type_expr ctx (e,p) (with_type:with_type) =
 			| TAbstract({a_impl = Some c} as a,pl) ->
 				if Meta.has Meta.CoreApi c.cl_meta then merge_core_doc c;
 				ctx.m.module_using <- c :: ctx.m.module_using;
+				let fields = try
+					let _,el,_ = Meta.get Meta.Forward a.a_meta in
+					let sl = ExtList.List.filter_map (fun e -> match fst e with
+						| EConst(Ident s) -> Some s
+						| _ -> None
+					) el in
+					let fields = get_fields (apply_params a.a_types pl a.a_this) in
+					if sl = [] then fields else PMap.fold (fun cf acc ->
+						if List.mem cf.cf_name sl then
+							PMap.add cf.cf_name cf acc
+						else
+							acc
+					) fields PMap.empty
+				with Not_found ->
+					PMap.empty
+				in
 				PMap.fold (fun f acc ->
 					if f.cf_name <> "_new" && can_access ctx c f true && Meta.has Meta.Impl f.cf_meta && not (Meta.has Meta.Enum f.cf_meta) then begin
 						let f = prepare_using_field f in
@@ -3096,7 +3120,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
 						PMap.add f.cf_name { f with cf_public = true; cf_type = opt_type t } acc
 					end else
 						acc
-				) c.cl_statics PMap.empty
+				) c.cl_statics fields
 			| TAnon a ->
 				(match !(a.a_status) with
 				| Statics c ->