Browse Source

minor collect_implementations cleanup (#9506)

* minor collect_implementations cleanup

did while trying to figure out #9504

* don't process already processed classes in collect_implementations

this can happen a lot with interfaces involved, also this workarounds messy cl_dependants situation (see https://github.com/HaxeFoundation/haxe/issues/9504#issuecomment-635548176)
Dan Korostelev 5 years ago
parent
commit
2776f3cd43
1 changed files with 17 additions and 14 deletions
  1. 17 14
      src/context/display/statistics.ml

+ 17 - 14
src/context/display/statistics.ml

@@ -70,21 +70,24 @@ let collect_statistics ctx pfilter with_expressions =
 		) c.cl_overrides
 	in
 	let collect_implementations c =
-		List.iter (fun cf ->
-			let rec loop c =
-				begin try
-					let cf' = PMap.find cf.cf_name c.cl_fields in
-					add_relation cf.cf_name_pos (Implemented,cf'.cf_name_pos)
-				with Not_found ->
-					()
-				end;
-				List.iter loop c.cl_descendants
-			in
-			List.iter loop c.cl_descendants
-		) c.cl_ordered_fields;
+		let memo = Hashtbl.create 0 in
 		let rec loop c' =
-			add_relation c.cl_name_pos ((if c'.cl_interface then Extended else Implemented),c'.cl_name_pos);
-			List.iter loop c'.cl_descendants
+			if not (Hashtbl.mem memo c'.cl_path) then begin
+				Hashtbl.add memo c'.cl_path true;
+				if c'.cl_interface then
+					add_relation c.cl_name_pos (Extended,c'.cl_name_pos)
+				else begin
+					add_relation c.cl_name_pos (Implemented,c'.cl_name_pos);
+					List.iter (fun cf ->
+						try
+							let cf' = PMap.find cf.cf_name c'.cl_fields in
+							add_relation cf.cf_name_pos (Implemented,cf'.cf_name_pos)
+						with Not_found ->
+							()
+					) c.cl_ordered_fields
+				end;
+				List.iter loop c'.cl_descendants
+			end
 		in
 		List.iter loop c.cl_descendants
 	in