浏览代码

filter duplicate toplevel identifiers (closes #6341)

Simon Krajewski 8 年之前
父节点
当前提交
1ba3d0bacb
共有 2 个文件被更改,包括 39 次插入7 次删除
  1. 15 7
      src/display/displayOutput.ml
  2. 24 0
      tests/display/src/cases/Toplevel.hx

+ 15 - 7
src/display/displayOutput.ml

@@ -60,22 +60,30 @@ let print_toplevel il =
 	Buffer.add_string b "<il>\n";
 	let s_type t = htmlescape (s_type (print_context()) t) in
 	let s_doc d = maybe_print_doc d in
+	let identifiers = Hashtbl.create 0 in
+	let check_ident s =
+		if Hashtbl.mem identifiers s then false
+		else begin
+			Hashtbl.add identifiers s true;
+			true
+		end
+	in
 	List.iter (fun id -> match id with
 		| IdentifierType.ITLocal v ->
-			Buffer.add_string b (Printf.sprintf "<i k=\"local\" t=\"%s\">%s</i>\n" (s_type v.v_type) v.v_name);
+			if check_ident v.v_name then Buffer.add_string b (Printf.sprintf "<i k=\"local\" t=\"%s\">%s</i>\n" (s_type v.v_type) v.v_name);
 		| IdentifierType.ITMember(c,cf) ->
-			Buffer.add_string b (Printf.sprintf "<i k=\"member\" t=\"%s\"%s>%s</i>\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name);
+			if check_ident cf.cf_name then Buffer.add_string b (Printf.sprintf "<i k=\"member\" t=\"%s\"%s>%s</i>\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name);
 		| IdentifierType.ITStatic(c,cf) ->
-			Buffer.add_string b (Printf.sprintf "<i k=\"static\" t=\"%s\"%s>%s</i>\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name);
+			if check_ident cf.cf_name then Buffer.add_string b (Printf.sprintf "<i k=\"static\" t=\"%s\"%s>%s</i>\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name);
 		| IdentifierType.ITEnum(en,ef) ->
-			Buffer.add_string b (Printf.sprintf "<i k=\"enum\" t=\"%s\"%s>%s</i>\n" (s_type ef.ef_type) (s_doc ef.ef_doc) ef.ef_name);
+			if check_ident ef.ef_name then Buffer.add_string b (Printf.sprintf "<i k=\"enum\" t=\"%s\"%s>%s</i>\n" (s_type ef.ef_type) (s_doc ef.ef_doc) ef.ef_name);
 		| IdentifierType.ITEnumAbstract(a,cf) ->
-			Buffer.add_string b (Printf.sprintf "<i k=\"enumabstract\" t=\"%s\"%s>%s</i>\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name);
+			if check_ident cf.cf_name then Buffer.add_string b (Printf.sprintf "<i k=\"enumabstract\" t=\"%s\"%s>%s</i>\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name);
 		| IdentifierType.ITGlobal(mt,s,t) ->
-			Buffer.add_string b (Printf.sprintf "<i k=\"global\" p=\"%s\" t=\"%s\">%s</i>\n" (s_type_path (t_infos mt).mt_path) (s_type t) s);
+			if check_ident s then Buffer.add_string b (Printf.sprintf "<i k=\"global\" p=\"%s\" t=\"%s\">%s</i>\n" (s_type_path (t_infos mt).mt_path) (s_type t) s);
 		| IdentifierType.ITType(mt) ->
 			let infos = t_infos mt in
-			Buffer.add_string b (Printf.sprintf "<i k=\"type\" p=\"%s\"%s>%s</i>\n" (s_type_path infos.mt_path) (s_doc infos.mt_doc) (snd infos.mt_path));
+			if check_ident (snd infos.mt_path) then Buffer.add_string b (Printf.sprintf "<i k=\"type\" p=\"%s\"%s>%s</i>\n" (s_type_path infos.mt_path) (s_doc infos.mt_doc) (snd infos.mt_path));
 		| IdentifierType.ITPackage s ->
 			Buffer.add_string b (Printf.sprintf "<i k=\"package\">%s</i>\n" s)
 		| IdentifierType.ITLiteral s ->

+ 24 - 0
tests/display/src/cases/Toplevel.hx

@@ -163,6 +163,30 @@ class Toplevel extends DisplayTestCase {
 		eq(true, hasToplevel(toplevel(pos(2)), "type", "FieldT2"));
 	}
 
+	/**
+	import cases.Toplevel.E.a;
+
+	enum E {
+		a;
+	}
+
+	class Main {
+		static var a:Int;
+		function new(a) {
+			{-1-}
+		}
+
+		static function main() {
+		}
+	}
+	**/
+	function testDuplicates() {
+		var toplevels = toplevel(pos(1));
+		toplevels = toplevels.filter(function(t) return t.name == "a");
+		eq(1, toplevels.length);
+		eq("local", toplevels[0].kind);
+	}
+
 	public static function hasToplevel(a:Array<ToplevelElement>, kind:String, name:String):Bool {
 		return a.exists(function(t) return t.kind == kind && t.name == name);
 	}