Преглед на файлове

[js] check abstracts for iterators (closes #5385)

Simon Krajewski преди 9 години
родител
ревизия
2cbed324e4
променени са 2 файла, в които са добавени 31 реда и са изтрити 2 реда
  1. 5 2
      src/generators/genjs.ml
  2. 26 0
      tests/unit/src/unit/issues/Issue5385.hx

+ 5 - 2
src/generators/genjs.ml

@@ -339,15 +339,18 @@ let this ctx = match ctx.in_value with None -> "this" | Some _ -> "$this"
 
 let is_dynamic_iterator ctx e =
 	let check x =
-		has_feature ctx "HxOverrides.iter" && (match follow x.etype with
+		let rec loop t = match follow t with
 			| TInst ({ cl_path = [],"Array" },_)
 			| TInst ({ cl_kind = KTypeParameter _}, _)
 			| TAnon _
 			| TDynamic _
 			| TMono _ ->
 				true
+			| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
+				loop (Abstract.get_underlying_type a tl)
 			| _ -> false
-		)
+		in
+		has_feature ctx "HxOverrides.iter" && loop x.etype
 	in
 	match e.eexpr with
 	| TField (x,f) when field_name f = "iterator" -> check x

+ 26 - 0
tests/unit/src/unit/issues/Issue5385.hx

@@ -0,0 +1,26 @@
+package unit.issues;
+
+class Issue5385 extends unit.Test {
+	function test() {
+		var refs:Refs = ["1"];
+		var myIter:MyIterator<String> = refs;
+		t(myIter.hasNext());
+		eq("1", myIter.next());
+	}
+}
+
+private abstract MyIterator<T>(Iterator<T>) from Iterator<T> to Iterator<T> {
+	@:from public static inline function fromIterable<T>(i:Iterable<T>)
+		return (i.iterator():MyIterator<T>);
+
+	public inline function hasNext() {
+		return this.hasNext();
+	}
+
+	public inline function next() {
+		return this.next();
+	}
+}
+
+@:forward
+private abstract Refs(Array<String>) from Array<String> to Array<String> {}