From 3b3f93249995bb91396f5cbe188c2bc461fab678 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 8 Feb 2023 20:40:46 +0100 Subject: [PATCH 1/3] propagate deprecated attribute for record fields --- analysis/src/CompletionBackEnd.ml | 8 ++++--- analysis/src/ProcessCmt.ml | 8 +++++++ analysis/src/SharedTypes.ml | 1 + analysis/tests/src/Completion.res | 17 +++++++++++++ .../tests/src/expected/Completion.res.txt | 24 +++++++++++++++++-- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index 7a62de8e6..dd6907491 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -130,6 +130,7 @@ let completionForExportedFields ~(env : QueryEnv.t) ~prefix ~exact ~namesUsed = let () = Hashtbl.add namesUsed name () in Some (Completion.create name ~env ~docstring:f.docstring + ?deprecated:f.deprecated ~kind: (Completion.Field (f, t.item.decl |> Shared.declToString t.name.txt))) @@ -740,7 +741,7 @@ let rec getCompletionsForContextPath ~full ~opens ~rawOpens ~allFiles ~pos ~env if Utils.checkName field.fname.txt ~prefix:fieldName ~exact then Some (Completion.create field.fname.txt ~env - ~docstring:field.docstring + ~docstring:field.docstring ?deprecated:field.deprecated ~kind: (Completion.Field ( field, @@ -1151,6 +1152,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode match (field.optional, mode) with | true, Pattern Destructuring -> Completion.create ("?" ^ field.fname.txt) + ?deprecated:field.deprecated ~docstring: [ field.fname.txt @@ -1161,7 +1163,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode (Field (field, TypeUtils.extractedTypeToString extractedType)) ~env | _ -> - Completion.create field.fname.txt + Completion.create field.fname.txt ?deprecated:field.deprecated ~kind: (Field (field, TypeUtils.extractedTypeToString extractedType)) ~env) @@ -1189,7 +1191,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode List.mem field.fname.txt seenFields = false) |> List.map (fun (field : field) -> Completion.create field.fname.txt ~kind:(Label "Inline record") - ~env) + ?deprecated:field.deprecated ~env) |> filterItems ~prefix | None -> if prefix = "" then diff --git a/analysis/src/ProcessCmt.ml b/analysis/src/ProcessCmt.ml index 67b910830..e45406461 100644 --- a/analysis/src/ProcessCmt.ml +++ b/analysis/src/ProcessCmt.ml @@ -27,6 +27,7 @@ let mapRecordField {Types.ld_id; ld_type; ld_attributes} = (match ProcessAttributes.findDocAttribute ld_attributes with | None -> [] | Some docstring -> [docstring]); + deprecated = ProcessAttributes.findDeprecatedAttribute ld_attributes; } let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) @@ -231,6 +232,10 @@ let forTypeDeclaration ~env ~(exported : Exported.t) with | None -> [] | Some docstring -> [docstring]); + deprecated = + ProcessAttributes + .findDeprecatedAttribute + f.ld_attributes; }))); res = (match cd_res with @@ -268,6 +273,9 @@ let forTypeDeclaration ~env ~(exported : Exported.t) Res_parsetree_viewer.hasOptionalAttribute ld_attributes; docstring = attrsToDocstring ld_attributes; + deprecated = + ProcessAttributes.findDeprecatedAttribute + ld_attributes; }))); } ~name ~stamp ~env typ_attributes diff --git a/analysis/src/SharedTypes.ml b/analysis/src/SharedTypes.ml index 622065cdd..52b8276c4 100644 --- a/analysis/src/SharedTypes.ml +++ b/analysis/src/SharedTypes.ml @@ -32,6 +32,7 @@ type field = { typ: Types.type_expr; optional: bool; docstring: string list; + deprecated: string option; } type constructorArgs = diff --git a/analysis/tests/src/Completion.res b/analysis/tests/src/Completion.res index dd1e90879..884520580 100644 --- a/analysis/tests/src/Completion.res +++ b/analysis/tests/src/Completion.res @@ -425,3 +425,20 @@ let ok = Ok(true) // ok->g // ^com + +type someRecordWithDeprecatedField = { + name: string, + @deprecated + someInt: int, + @deprecated("Use 'someInt'.") + someFloat: float, +} + +let rWithDepr: someRecordWithDeprecatedField = { + name: "hej", + someInt: 12, + someFloat: 12., +} + +// rWithDepr.so +// ^com diff --git a/analysis/tests/src/expected/Completion.res.txt b/analysis/tests/src/expected/Completion.res.txt index b36ab0940..b6508cd66 100644 --- a/analysis/tests/src/expected/Completion.res.txt +++ b/analysis/tests/src/expected/Completion.res.txt @@ -1625,8 +1625,8 @@ Resolved opens 2 Completion.res Completion.res }] Complete src/Completion.res 405:22 -posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:11->428:0] -Pexp_apply ...__ghost__[0:-1->0:-1] (...[405:11->423:17], ...[428:0->428:0]) +posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:11->445:0] +Pexp_apply ...__ghost__[0:-1->0:-1] (...[405:11->423:17], ...[428:0->445:0]) posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:11->423:17] Pexp_apply ...__ghost__[0:-1->0:-1] (...[405:11->405:19], ...[405:21->423:17]) posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:21->423:17] @@ -1759,3 +1759,23 @@ Resolved opens 2 Completion.res Completion.res "documentation": {"kind": "markdown", "value": "\n `getWithDefault(res, defaultValue)`: If `res` is `Ok(n)`, returns `n`,\n otherwise `default`\n\n ```res example\n Belt.Result.getWithDefault(Ok(42), 0) == 42\n\n Belt.Result.getWithDefault(Error(\"Invalid Data\"), 0) == 0\n ```\n"} }] +Complete src/Completion.res 442:15 +posCursor:[442:15] posNoWhite:[442:14] Found expr:[442:3->442:15] +Pexp_field [442:3->442:12] so:[442:13->442:15] +Completable: Cpath Value[rWithDepr].so +Raw opens: 2 Shadow.B.place holder ... Shadow.A.place holder +Resolved opens 2 Completion.res Completion.res +[{ + "label": "someInt", + "kind": 5, + "tags": [1], + "detail": "someInt: int\n\ntype someRecordWithDeprecatedField = {\n name: string,\n someInt: int,\n someFloat: float,\n}", + "documentation": {"kind": "markdown", "value": "Deprecated: \n\n"} + }, { + "label": "someFloat", + "kind": 5, + "tags": [1], + "detail": "someFloat: float\n\ntype someRecordWithDeprecatedField = {\n name: string,\n someInt: int,\n someFloat: float,\n}", + "documentation": {"kind": "markdown", "value": "Deprecated: Use 'someInt'.\n\n"} + }] + From 2a832b433468b11406ec3434ea225c804b4057ed Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 8 Feb 2023 20:46:23 +0100 Subject: [PATCH 2/3] propagate deprecated for constructors --- analysis/src/CompletionBackEnd.ml | 3 +- analysis/src/ProcessCmt.ml | 6 +++ analysis/src/SharedTypes.ml | 7 ++-- analysis/tests/src/Completion.res | 8 ++++ .../tests/src/expected/Completion.res.txt | 41 ++++++++++++++++--- 5 files changed, 56 insertions(+), 9 deletions(-) diff --git a/analysis/src/CompletionBackEnd.ml b/analysis/src/CompletionBackEnd.ml index dd6907491..9eee9cdab 100644 --- a/analysis/src/CompletionBackEnd.ml +++ b/analysis/src/CompletionBackEnd.ml @@ -108,6 +108,7 @@ let completionsForExportedConstructors ~(env : QueryEnv.t) ~prefix ~exact let () = Hashtbl.add namesUsed name () in Some (Completion.create name ~env ~docstring:c.docstring + ?deprecated:c.deprecated ~kind: (Completion.Constructor (c, t.item.decl |> Shared.declToString t.name.txt))) @@ -1073,7 +1074,7 @@ let rec completeTypedValue ~full ~prefix ~completionContext ~mode | InlineRecord _ -> 1 | Args args -> List.length args in - Completion.createWithSnippet + Completion.createWithSnippet ?deprecated:constructor.deprecated ~name: (constructor.cname.txt ^ printConstructorArgs numArgs ~asSnippet:false) diff --git a/analysis/src/ProcessCmt.ml b/analysis/src/ProcessCmt.ml index e45406461..329af53fc 100644 --- a/analysis/src/ProcessCmt.ml +++ b/analysis/src/ProcessCmt.ml @@ -100,6 +100,9 @@ let rec forTypeSignatureItem ~(env : SharedTypes.Env.t) ~(exported : Exported.t) res = cd_res; typeDecl = (name, decl); docstring = attrsToDocstring cd_attributes; + deprecated = + ProcessAttributes.findDeprecatedAttribute + cd_attributes; } in let declared = @@ -201,6 +204,9 @@ let forTypeDeclaration ~env ~(exported : Exported.t) { Constructor.stamp; cname; + deprecated = + ProcessAttributes.findDeprecatedAttribute + cd_attributes; args = (match cd_args with | Cstr_tuple args -> diff --git a/analysis/src/SharedTypes.ml b/analysis/src/SharedTypes.ml index 52b8276c4..c84aabf25 100644 --- a/analysis/src/SharedTypes.ml +++ b/analysis/src/SharedTypes.ml @@ -47,6 +47,7 @@ module Constructor = struct res: Types.type_expr option; typeDecl: string * Types.type_declaration; docstring: string list; + deprecated: string option; } end @@ -368,12 +369,12 @@ module Completion = struct detail; } - let createWithSnippet ~name ?insertText ~kind ~env ?sortText ?filterText - ?(docstring = []) () = + let createWithSnippet ~name ?insertText ~kind ~env ?sortText ?deprecated + ?filterText ?(docstring = []) () = { name; env; - deprecated = None; + deprecated; docstring; kind; sortText; diff --git a/analysis/tests/src/Completion.res b/analysis/tests/src/Completion.res index 884520580..9246c2bdd 100644 --- a/analysis/tests/src/Completion.res +++ b/analysis/tests/src/Completion.res @@ -440,5 +440,13 @@ let rWithDepr: someRecordWithDeprecatedField = { someFloat: 12., } +// Should show deprecated status // rWithDepr.so // ^com + +type someVariantWithDeprecated = + | @deprecated DoNotUseMe | UseMeInstead | @deprecated("Use 'UseMeInstead'") AndNotMe + +// Should show deprecated status +// let v: someVariantWithDeprecated = +// ^com diff --git a/analysis/tests/src/expected/Completion.res.txt b/analysis/tests/src/expected/Completion.res.txt index b6508cd66..c98e1a2c8 100644 --- a/analysis/tests/src/expected/Completion.res.txt +++ b/analysis/tests/src/expected/Completion.res.txt @@ -1625,8 +1625,8 @@ Resolved opens 2 Completion.res Completion.res }] Complete src/Completion.res 405:22 -posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:11->445:0] -Pexp_apply ...__ghost__[0:-1->0:-1] (...[405:11->423:17], ...[428:0->445:0]) +posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:11->453:0] +Pexp_apply ...__ghost__[0:-1->0:-1] (...[405:11->423:17], ...[428:0->453:0]) posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:11->423:17] Pexp_apply ...__ghost__[0:-1->0:-1] (...[405:11->405:19], ...[405:21->423:17]) posCursor:[405:22] posNoWhite:[405:21] Found expr:[405:21->423:17] @@ -1759,9 +1759,9 @@ Resolved opens 2 Completion.res Completion.res "documentation": {"kind": "markdown", "value": "\n `getWithDefault(res, defaultValue)`: If `res` is `Ok(n)`, returns `n`,\n otherwise `default`\n\n ```res example\n Belt.Result.getWithDefault(Ok(42), 0) == 42\n\n Belt.Result.getWithDefault(Error(\"Invalid Data\"), 0) == 0\n ```\n"} }] -Complete src/Completion.res 442:15 -posCursor:[442:15] posNoWhite:[442:14] Found expr:[442:3->442:15] -Pexp_field [442:3->442:12] so:[442:13->442:15] +Complete src/Completion.res 443:15 +posCursor:[443:15] posNoWhite:[443:14] Found expr:[443:3->443:15] +Pexp_field [443:3->443:12] so:[443:13->443:15] Completable: Cpath Value[rWithDepr].so Raw opens: 2 Shadow.B.place holder ... Shadow.A.place holder Resolved opens 2 Completion.res Completion.res @@ -1779,3 +1779,34 @@ Resolved opens 2 Completion.res Completion.res "documentation": {"kind": "markdown", "value": "Deprecated: Use 'someInt'.\n\n"} }] +Complete src/Completion.res 450:37 +XXX Not found! +Completable: Cexpression Type[someVariantWithDeprecated] +Raw opens: 2 Shadow.B.place holder ... Shadow.A.place holder +Resolved opens 2 Completion.res Completion.res +[{ + "label": "DoNotUseMe", + "kind": 4, + "tags": [1], + "detail": "DoNotUseMe\n\ntype someVariantWithDeprecated =\n | DoNotUseMe\n | UseMeInstead\n | AndNotMe", + "documentation": {"kind": "markdown", "value": "Deprecated: \n\n"}, + "insertText": "DoNotUseMe", + "insertTextFormat": 2 + }, { + "label": "UseMeInstead", + "kind": 4, + "tags": [], + "detail": "UseMeInstead\n\ntype someVariantWithDeprecated =\n | DoNotUseMe\n | UseMeInstead\n | AndNotMe", + "documentation": null, + "insertText": "UseMeInstead", + "insertTextFormat": 2 + }, { + "label": "AndNotMe", + "kind": 4, + "tags": [1], + "detail": "AndNotMe\n\ntype someVariantWithDeprecated =\n | DoNotUseMe\n | UseMeInstead\n | AndNotMe", + "documentation": {"kind": "markdown", "value": "Deprecated: Use 'UseMeInstead'\n\n"}, + "insertText": "AndNotMe", + "insertTextFormat": 2 + }] + From 5ad242e49c30e5962d5f04a44cb94766eedce33d Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 8 Feb 2023 20:47:49 +0100 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 906757ea2..49a2af97a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ #### :nail_care: Polish - Signature Help is now considered stable, and enabled for all users. Can still be turned off in settings. +- Show whether record fields and variant constructors are deprecated when completing. https://github.com/rescript-lang/rescript-vscode/pull/731 ## 1.12.0