Prechádzať zdrojové kódy

Diagnostics update (#11207)

* [diagnostics] change order of sub error lines

* [diagnostics] turn tuple into record, add diagnostic code

* [tests] update diagnostics in tests
Rudy Ges 2 rokov pred
rodič
commit
d1f8058901

+ 3 - 2
src/compiler/displayProcessing.ml

@@ -95,10 +95,11 @@ let process_display_configuration ctx =
 		com.info <- (fun ?depth ?from_macro s p ->
 			add_diagnostics_message ?depth com s p DKCompilerMessage Information
 		);
-		com.warning <- (fun ?depth ?from_macro w options s p ->
+		com.warning <- (fun ?(depth = 0) ?from_macro w options s p ->
 			match Warning.get_mode w (com.warning_options @ options) with
 			| WMEnable ->
-				add_diagnostics_message ?depth com s p DKCompilerMessage Warning
+				let wobj = Warning.warning_obj w in
+				add_diagnostics_message ~depth ~code:(Some wobj.w_name) com s p DKCompilerMessage Warning
 			| WMDisable ->
 				()
 		);

+ 3 - 3
src/context/common.ml

@@ -233,7 +233,7 @@ class file_keys = object(self)
 end
 
 type shared_display_information = {
-	mutable diagnostics_messages : (string * pos * MessageKind.t * MessageSeverity.t * int (* depth *)) list;
+	mutable diagnostics_messages : diagnostic list;
 }
 
 type display_information = {
@@ -1248,10 +1248,10 @@ let utf16_to_utf8 str =
 	loop 0;
 	Buffer.contents b
 
-let add_diagnostics_message ?(depth = 0) com s p kind sev =
+let add_diagnostics_message ?(depth = 0) ?(code = None) com s p kind sev =
 	if sev = MessageSeverity.Error then com.has_error <- true;
 	let di = com.shared.shared_display_information in
-	di.diagnostics_messages <- (s,p,kind,sev,depth) :: di.diagnostics_messages
+	di.diagnostics_messages <- (make_diagnostic ~depth ~code s p kind sev) :: di.diagnostics_messages
 
 let display_error_ext com err =
 	if is_diagnostics com then begin

+ 3 - 1
src/context/display/diagnostics.ml

@@ -39,9 +39,11 @@ let find_unused_variables com e =
 let check_other_things com e =
 	let had_effect = ref false in
 	let no_effect p =
+		(* TODO warning code? *)
 		add_diagnostics_message com "This code has no effect" p DKCompilerMessage Warning;
 	in
 	let pointless_compound s p =
+		(* TODO warning code? *)
 		add_diagnostics_message com (Printf.sprintf "This %s has no effect, but some of its sub-expressions do" s) p DKCompilerMessage Warning;
 	in
 	let rec compound s el p =
@@ -141,7 +143,7 @@ let prepare com =
 		unresolved_identifiers = [];
 		missing_fields = PMap.empty;
 	} in
-	if not (List.exists (fun (_,_,_,sev,_) -> sev = MessageSeverity.Error) com.shared.shared_display_information.diagnostics_messages) then
+	if not (List.exists (fun diag -> diag.diag_severity = MessageSeverity.Error) com.shared.shared_display_information.diagnostics_messages) then
 		collect_diagnostics dctx com;
 	let process_modules com =
 		List.iter (fun m ->

+ 23 - 16
src/context/display/diagnosticsPrinter.ml

@@ -10,14 +10,16 @@ type t = {
 	diag_kind : MessageKind.t;
 	diag_pos : pos;
 	diag_severity : MessageSeverity.t;
+	diag_code : string option;
 	diag_args : Json.t;
 	mutable diag_related_information : (pos * int * string) list;
 }
 
-let make_diagnostic kd p sev args = {
+let make_diagnostic kd p sev code args = {
 	diag_kind = kd;
 	diag_pos = p;
 	diag_severity = sev;
+	diag_code = code;
 	diag_args = args;
 	diag_related_information = [];
 }
@@ -59,7 +61,7 @@ let json_of_diagnostics com dctx =
 			Hashtbl.replace diagnostics file (diag :: fdiag)
 	in
 	let file_keys = new Common.file_keys in
-	let add dk p sev args =
+	let add dk p sev code args =
 		let append = match dk with
 			| DKUnusedImport
 			| DKRemovableCode
@@ -73,7 +75,7 @@ let json_of_diagnostics com dctx =
 				true
 		in
 		if p = null_pos || is_diagnostics_file com (file_keys#get p.pfile) then begin
-			let diag = make_diagnostic dk p sev args in
+			let diag = make_diagnostic dk p sev code args in
 			current := Some diag;
 			add append diag
 		end else current := None
@@ -96,19 +98,19 @@ let json_of_diagnostics com dctx =
 					"name",JString s;
 				])
 		) suggestions in
-		add DKUnresolvedIdentifier p MessageSeverity.Error (JArray suggestions);
+		add DKUnresolvedIdentifier p MessageSeverity.Error None (JArray suggestions);
 	) dctx.unresolved_identifiers;
-	List.iter (fun (s,p,kind,sev,depth) -> match (depth, !current) with
-		| d, Some diag when d > 0 ->
-			let lines = ExtString.String.nsplit s "\n" in
+	List.iter (fun d -> match (d.diag_depth, !current) with
+		| depth, Some diag when depth > 0 ->
+			let lines = ExtString.String.nsplit d.diag_message "\n" in
 			(match lines with
 				| [] -> ()
 				| s :: sub ->
-					let related = List.fold_left (fun acc s -> (p,d,Error.compl_msg s) :: acc) diag.diag_related_information sub in
-					diag.diag_related_information <- (p,d,s) :: related;
+					let related = List.fold_left (fun acc s -> (d.diag_pos,depth,Error.compl_msg s) :: acc) [] (List.rev sub) in
+					diag.diag_related_information <- List.append diag.diag_related_information ((d.diag_pos,depth,s) :: related);
 			)
 		| 0, _ ->
-			add kind p sev (JString s)
+			add d.diag_kind d.diag_pos d.diag_severity d.diag_code (JString d.diag_message)
 		| _ ->
 			(* Do not add errors with depth greater than one as top level diagnostic. *)
 			(* This could happen when running diagnostics for a file that is wentioned in *)
@@ -176,22 +178,25 @@ let json_of_diagnostics com dctx =
 			"moduleFile",jstring (Path.UniqueKey.lazy_path (t_infos mt).mt_module.m_extra.m_file);
 			"entries",jarray l
 		] in
-		add DKMissingFields p MessageSeverity.Error j
+		add DKMissingFields p MessageSeverity.Error None j
 	) dctx.missing_fields;
 	(* non-append from here *)
 	begin match Warning.get_mode WDeprecated com.warning_options with
 	| WMEnable ->
 		Hashtbl.iter (fun _ (s,p) ->
-			add DKDeprecationWarning p MessageSeverity.Warning (JString s);
+			let wobj = Warning.warning_obj WDeprecated in
+			add DKDeprecationWarning p MessageSeverity.Warning (Some wobj.w_name) (JString s);
 		) DeprecationCheck.warned_positions;
 	| WMDisable ->
 		()
 	end;
 	PMap.iter (fun p r ->
-		if not !r then add DKUnusedImport p MessageSeverity.Warning (JArray [])
+		(* TODO warning code? *)
+		if not !r then add DKUnusedImport p MessageSeverity.Warning None (JArray [])
 	) dctx.import_positions;
 	List.iter (fun (s,p,prange) ->
-		add DKRemovableCode p MessageSeverity.Warning (JObject ["description",JString s;"range",if prange = null_pos then JNull else Genjson.generate_pos_as_range prange])
+		(* TODO warning code? *)
+		add DKRemovableCode p MessageSeverity.Warning None (JObject ["description",JString s;"range",if prange = null_pos then JNull else Genjson.generate_pos_as_range prange])
 	) dctx.removable_code;
 	Hashtbl.iter (fun file ranges ->
 		List.iter (fun (p,e) ->
@@ -200,7 +205,8 @@ let json_of_diagnostics com dctx =
 					"string",JString (Ast.Printer.s_expr e)
 				]
 			] in
-			add DKInactiveBlock p MessageSeverity.Hint jo
+			(* TODO warning code? *)
+			add DKInactiveBlock p MessageSeverity.Hint None jo
 		) ranges
 	) dctx.dead_blocks;
 	let jl = Hashtbl.fold (fun file diag acc ->
@@ -210,8 +216,9 @@ let json_of_diagnostics com dctx =
 				"severity",JInt (MessageSeverity.to_int diag.diag_severity);
 				"range",Genjson.generate_pos_as_range diag.diag_pos;
 				"args",diag.diag_args;
+				"code",(match diag.diag_code with None -> JNull | Some c -> JString c);
 				"relatedInformation",JArray (
-					List.rev_map (fun (pos,depth,msg) -> (JObject [
+					List.map (fun (pos,depth,msg) -> (JObject [
 						"location",Genjson.generate_pos_as_location pos;
 						"depth",JInt depth;
 						"message",JString msg;

+ 1 - 1
src/core/displayTypes.ml

@@ -330,7 +330,7 @@ type diagnostics_context = {
 	mutable import_positions : (pos,bool ref) PMap.t;
 	mutable dead_blocks : (Path.UniqueKey.t,(pos * expr) list) Hashtbl.t;
 	mutable unresolved_identifiers : (string * pos * (string * CompletionItem.t * int) list) list;
-	mutable diagnostics_messages : (string * pos * MessageKind.t * MessageSeverity.t * int (* depth *)) list;
+	mutable diagnostics_messages : diagnostic list;
 	mutable missing_fields : (pos,(module_type * (missing_fields_diagnostics list ref))) PMap.t;
 }
 

+ 24 - 6
src/core/globals.ml

@@ -185,12 +185,30 @@ type compiler_message = {
 }
 
 let make_compiler_message ?(from_macro = false) msg p depth kind sev = {
-		cm_message = msg;
-		cm_pos = p;
-		cm_depth = depth;
-		cm_from_macro = from_macro;
-		cm_kind = kind;
-		cm_severity = sev;
+	cm_message = msg;
+	cm_pos = p;
+	cm_depth = depth;
+	cm_from_macro = from_macro;
+	cm_kind = kind;
+	cm_severity = sev;
+}
+
+type diagnostic = {
+	diag_message : string;
+	diag_code : string option;
+	diag_pos : pos;
+	diag_kind : MessageKind.t;
+	diag_severity : MessageSeverity.t;
+	diag_depth : int;
+}
+
+let make_diagnostic ?(depth = 0) ?(code = None) message pos kind sev = {
+	diag_message = message;
+	diag_pos = pos;
+	diag_code = code;
+	diag_kind = kind;
+	diag_severity = sev;
+	diag_depth = depth;
 }
 
 let i32_31 = Int32.of_int 31

+ 1 - 0
tests/display/src/Diagnostic.hx

@@ -67,6 +67,7 @@ typedef Diagnostic<T> = {
 	var range:Range;
 	var severity:DiagnosticSeverity;
 	var args:T;
+	var code:Null<String>;
 	var relatedInformation:Array<DiagnosticRelatedInformation>;
 }
 

+ 1 - 0
tests/display/src/cases/Issue10194.hx

@@ -14,6 +14,7 @@ class Issue10194 extends DisplayTestCase {
 			{
 				kind: DKCompilerError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "String should be Int\nFor function argument 'a'"

+ 2 - 0
tests/display/src/cases/Issue11173.hx

@@ -27,6 +27,7 @@ class Issue11173 extends DisplayTestCase {
 			{
 				kind: DKCompilerError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(3), pos(4)),
 				relatedInformation: [],
 				args: "This expression cannot be accessed for writing"
@@ -34,6 +35,7 @@ class Issue11173 extends DisplayTestCase {
 			{
 				kind: DKCompilerError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(5), pos(6)),
 				relatedInformation: [],
 				args: "This expression cannot be accessed for writing"

+ 2 - 0
tests/display/src/cases/Issue5306.hx

@@ -24,6 +24,7 @@ class Issue5306 extends DisplayTestCase {
 				kind: DKParserError,
 				range: diagnosticsRange(pos(5), pos(6)),
 				severity: Error,
+				code: null,
 				relatedInformation: [],
 				args: "Missing ;"
 			},
@@ -31,6 +32,7 @@ class Issue5306 extends DisplayTestCase {
 				kind: DKCompilerError,
 				range: diagnosticsRange(pos(3), pos(4)),
 				severity: Error,
+				code: null,
 				relatedInformation: [],
 				args: "Type not found : InvalidType"
 			}

+ 1 - 0
tests/display/src/cases/Issue7777.hx

@@ -18,6 +18,7 @@ class Issue7777 extends DisplayTestCase {
 			{
 				kind: DKUnusedImport,
 				severity: Warning,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: []

+ 1 - 0
tests/display/src/cases/Issue7932.hx

@@ -12,6 +12,7 @@ class Issue7932 extends DisplayTestCase {
 				kind: DKParserError,
 				range: diagnosticsRange(pos(1), pos(2)),
 				severity: Error,
+				code: null,
 				relatedInformation: [],
 				args: "Expected type parameter"
 			}

+ 1 - 0
tests/display/src/cases/Issue7935.hx

@@ -40,6 +40,7 @@ class Issue7935 extends DisplayTestCase {
 				kind: DKParserError,
 				range: diagnosticsRange(pos(1), pos(2)),
 				severity: Error,
+				code: null,
 				relatedInformation: [],
 				args: message
 			}

+ 1 - 0
tests/display/src/cases/Issue7938.hx

@@ -12,6 +12,7 @@ class Issue7938 extends DisplayTestCase {
 				kind: DKParserError,
 				range: diagnosticsRange(pos(1), pos(2)),
 				severity: Error,
+				code: null,
 				relatedInformation: [],
 				args: "Unexpected fuction"
 			}

+ 1 - 0
tests/display/src/cases/Issue7939.hx

@@ -10,6 +10,7 @@ class Issue7939 extends DisplayTestCase {
 				kind: DKParserError,
 				range: diagnosticsRange(pos(1), pos(2)),
 				severity: Error,
+				code: null,
 				relatedInformation: [],
 				args: "Unexpected {"
 			}

+ 1 - 0
tests/display/src/cases/Issue7940.hx

@@ -14,6 +14,7 @@ class Issue7940 extends DisplayTestCase {
 				kind: DKParserError,
 				range: diagnosticsRange(pos(1), pos(1)),
 				severity: Error,
+				code: null,
 				relatedInformation: [],
 				args: "Unterminated string"
 			}

+ 1 - 0
tests/display/src/cases/Issue7943.hx

@@ -13,6 +13,7 @@ class Issue7943 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(3), pos(4)),
 				relatedInformation: [],
 				args: "Missing ;"

+ 1 - 0
tests/display/src/cases/Issue7944.hx

@@ -13,6 +13,7 @@ class Issue7944 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Unexpected fun"

+ 2 - 0
tests/display/src/cases/Issue7945.hx

@@ -9,6 +9,7 @@ class Issue7945 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Expected { or to or from"
@@ -24,6 +25,7 @@ class Issue7945 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Expected extends or implements or {"

+ 2 - 0
tests/display/src/cases/Issue7946.hx

@@ -9,6 +9,7 @@ class Issue7946 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Unexpected open"
@@ -24,6 +25,7 @@ class Issue7946 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Unexpected clas"

+ 2 - 0
tests/display/src/cases/Issue7947.hx

@@ -21,6 +21,7 @@ class Issue7947 extends DisplayTestCase {
 			{
 				kind: DKCompilerError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Void should be Bool"
@@ -48,6 +49,7 @@ class Issue7947 extends DisplayTestCase {
 			{
 				kind: DKCompilerError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Bool should be Void"

+ 2 - 0
tests/display/src/cases/Issue7948.hx

@@ -13,6 +13,7 @@ class Issue7948 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: 'Unexpected keyword "class"'
@@ -32,6 +33,7 @@ class Issue7948 extends DisplayTestCase {
 			{
 				kind: DKParserError,
 				severity: Error,
+				code: null,
 				range: diagnosticsRange(pos(1), pos(2)),
 				relatedInformation: [],
 				args: "Unexpected }"

+ 1 - 1
tests/misc/projects/Issue11020/compile.hxml.stderr

@@ -1 +1 @@
-[{"file":"$$normPath(::cwd::/,true)Main.hx","diagnostics":[{"kind":2,"severity":3,"range":{"start":{"line":2,"character":1},"end":{"line":2,"character":19}},"args":"Context.info","relatedInformation":[]},{"kind":2,"severity":2,"range":{"start":{"line":2,"character":1},"end":{"line":2,"character":19}},"args":"Context.warning","relatedInformation":[]},{"kind":2,"severity":1,"range":{"start":{"line":2,"character":1},"end":{"line":2,"character":19}},"args":"Context.error","relatedInformation":[]},{"kind":2,"severity":1,"range":{"start":{"line":0,"character":11},"end":{"line":0,"character":18}},"args":"Build failure","relatedInformation":[]}]}]
+[{"file":"$$normPath(::cwd::/,true)Main.hx","diagnostics":[{"kind":2,"severity":3,"range":{"start":{"line":2,"character":1},"end":{"line":2,"character":19}},"args":"Context.info","code":null,"relatedInformation":[]},{"kind":2,"severity":2,"range":{"start":{"line":2,"character":1},"end":{"line":2,"character":19}},"args":"Context.warning","code":"WUser","relatedInformation":[]},{"kind":2,"severity":1,"range":{"start":{"line":2,"character":1},"end":{"line":2,"character":19}},"args":"Context.error","code":null,"relatedInformation":[]},{"kind":2,"severity":1,"range":{"start":{"line":0,"character":11},"end":{"line":0,"character":18}},"args":"Build failure","code":null,"relatedInformation":[]}]}]

+ 1 - 1
tests/misc/projects/Issue6794/compile.hxml.stderr

@@ -1 +1 @@
-[{"file":"$$normPath(::cwd::/,true)Main.hx","diagnostics":[{"kind":2,"severity":2,"range":{"start":{"line":13,"character":42},"end":{"line":13,"character":43}},"args":"foo","relatedInformation":[]}]}]
+[{"file":"$$normPath(::cwd::/,true)Main.hx","diagnostics":[{"kind":2,"severity":2,"range":{"start":{"line":13,"character":42},"end":{"line":13,"character":43}},"args":"foo","code":"WUser","relatedInformation":[]}]}]

+ 1 - 1
tests/misc/projects/Issue9676/compile1D.hxml.stderr

@@ -1 +1 @@
-[{"file":"$$normPath(::cwd::/,true)MainField.hx","diagnostics":[{"kind":4,"severity":1,"range":{"start":{"line":1,"character":8},"end":{"line":1,"character":17}},"args":"`final var` is not supported, use `final` instead","relatedInformation":[]}]}]
+[{"file":"$$normPath(::cwd::/,true)MainField.hx","diagnostics":[{"kind":4,"severity":1,"range":{"start":{"line":1,"character":8},"end":{"line":1,"character":17}},"args":"`final var` is not supported, use `final` instead","code":null,"relatedInformation":[]}]}]

+ 1 - 1
tests/misc/projects/Issue9676/compile2D.hxml.stderr

@@ -1 +1 @@
-[{"file":"$$normPath(::cwd::/,true)MainExpr.hx","diagnostics":[{"kind":4,"severity":1,"range":{"start":{"line":1,"character":1},"end":{"line":1,"character":10}},"args":"`final var` is not supported, use `final` instead","relatedInformation":[]}]}]
+[{"file":"$$normPath(::cwd::/,true)MainExpr.hx","diagnostics":[{"kind":4,"severity":1,"range":{"start":{"line":1,"character":1},"end":{"line":1,"character":10}},"args":"`final var` is not supported, use `final` instead","code":null,"relatedInformation":[]}]}]

+ 1 - 1
tests/misc/projects/Issue9676/compile3D.hxml.stderr

@@ -1 +1 @@
-[{"file":"$$normPath(::cwd::/,true)MainMacro.hx","diagnostics":[{"kind":4,"severity":1,"range":{"start":{"line":1,"character":7},"end":{"line":1,"character":16}},"args":"`final var` is not supported, use `final` instead","relatedInformation":[]}]}]
+[{"file":"$$normPath(::cwd::/,true)MainMacro.hx","diagnostics":[{"kind":4,"severity":1,"range":{"start":{"line":1,"character":7},"end":{"line":1,"character":16}},"args":"`final var` is not supported, use `final` instead","code":null,"relatedInformation":[]}]}]