Browse Source

allow arguments to @:multiType which are interpreted as relevant type parameters (closes #2494)

Simon Krajewski 11 years ago
parent
commit
532fbbfa69
3 changed files with 16 additions and 5 deletions
  1. 13 2
      codegen.ml
  2. 1 1
      common.ml
  3. 2 2
      std/Map.hx

+ 13 - 2
codegen.ml

@@ -684,10 +684,21 @@ module Abstract = struct
 
 	let find_multitype_specialization a pl p =
 		let m = mk_mono() in
-		let at = apply_params a.a_types pl a.a_this in
+		let tl = match Meta.get Meta.MultiType a.a_meta with
+			| _,[],_ -> pl
+			| _,el,_ ->
+				let relevant = Hashtbl.create 0 in
+				List.iter (fun e -> match fst e with
+					| EConst(Ident s) -> Hashtbl.replace relevant s true
+					| _ -> error "Type parameter expected" (pos e)
+				) el;
+				let tl = List.map2 (fun (n,_) t -> if Hashtbl.mem relevant n || not (has_mono t) then t else t_dynamic) a.a_types pl in
+				tl
+		in
 		let _,cfo =
-			try find_to a pl m
+			try find_to a tl m
 			with Not_found ->
+				let at = apply_params a.a_types pl a.a_this in
 				let st = s_type (print_context()) at in
 				if has_mono at then
 					error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p

+ 1 - 1
common.ml

@@ -381,7 +381,7 @@ module MetaInfo = struct
 		| Macro -> ":macro",("(deprecated)",[])
 		| MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[Internal])
 		| MergeBlock -> ":mergeBlock",("Internally used by typer to mark block that should be merged into the outer scope",[Internal])
-		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract])
+		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract; HasParam "Relevant type parameters"])
 		| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
 		| NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum]])
 		| NativeGeneric -> ":nativeGeneric",("Used internally to annotate native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])

+ 2 - 2
std/Map.hx

@@ -41,7 +41,7 @@ import haxe.ds.EnumValueMap;
 	
 	Map is an abstract type, it is not available at runtime.
 **/
-@:multiType
+@:multiType(K)
 abstract Map<K,V>(IMap<K,V> ) {
 	
 	/**
@@ -79,7 +79,7 @@ abstract Map<K,V>(IMap<K,V> ) {
 		1. the map has no mapping for `key`
 		2. the map has a mapping with a value of `null`
 		
-		If it is important to distinguish these cases, `exists()` should be 
+		If it is important to distinguish these cases, `exists()` should be
 		used.
 		
 		If `key` is null, the result is unspecified.