From e8cb3577ca3cbe0d83a5c5d6a2331e6363ec959a Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 16 Aug 2023 15:55:19 +0200 Subject: [PATCH 1/2] add code action for wrapping option patterns in Some when not already wrapped --- server/src/codeActions.ts | 72 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/server/src/codeActions.ts b/server/src/codeActions.ts index 670378ad8..a28c9b3d5 100644 --- a/server/src/codeActions.ts +++ b/server/src/codeActions.ts @@ -156,6 +156,7 @@ export let findCodeActionsInDiagnosticsMessage = ({ simpleConversion, applyUncurried, simpleAddMissingCases, + wrapInSome, ]; for (let extractCodeAction of codeActionEtractors) { @@ -240,6 +241,77 @@ let didYouMeanAction: codeActionExtractor = ({ return false; }; +// This action offers to wrap patterns that aren't option in Some. +let wrapInSome: codeActionExtractor = ({ + codeActions, + diagnostic, + file, + line, + range, + array, + index, +}) => { + if (line.startsWith("This pattern matches values of type")) { + let regex = /This pattern matches values of type (.*)$/; + + let match = line.match(regex); + + if (match === null) { + return false; + } + + let [_, type] = match; + + if (!type.startsWith("option<")) { + // Look for the expected type + let restOfMessage = array.slice(index + 1); + let lineIndexWithType = restOfMessage.findIndex((l) => + l + .trim() + .startsWith("but a pattern was expected which matches values of type") + ); + + if (lineIndexWithType === -1) return false; + // The type is either on this line or the next + let [_, typ = ""] = restOfMessage[lineIndexWithType].split( + "but a pattern was expected which matches values of type" + ); + + console.log({ typ }); + + if (typ.trim() === "") { + // Type is on the next line + typ = (restOfMessage[lineIndexWithType + 1] ?? "").trim(); + } + + if (typ.trim().startsWith("option<")) { + codeActions[file] = codeActions[file] || []; + + let codeAction: p.CodeAction = { + title: `Wrap in option Some`, + edit: { + changes: { + [file]: wrapRangeInText(range, `Some(`, `)`), + }, + }, + diagnostics: [diagnostic], + kind: p.CodeActionKind.QuickFix, + isPreferred: true, + }; + + codeActions[file].push({ + range, + codeAction, + }); + + return true; + } + } + } + + return false; +}; + // This action handles when the compiler errors on certain fields of a record // being undefined. We then offers an action that inserts all of the record // fields, with an `assert false` dummy value. `assert false` is so applying the From 0e48443972737bd749e93ee6542aa7c0f4b13d66 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 16 Aug 2023 15:59:01 +0200 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + server/src/codeActions.ts | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b26ef21b..a0cba02a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Add support for syntax highlighting in `%raw` and `%ffi` extension points. https://github.com/rescript-lang/rescript-vscode/pull/774 - Add completion to top level decorators. https://github.com/rescript-lang/rescript-vscode/pull/799 +- Add code action for wrapping patterns where option is expected with `Some`. https://github.com/rescript-lang/rescript-vscode/pull/806 #### :nail_care: Polish diff --git a/server/src/codeActions.ts b/server/src/codeActions.ts index a28c9b3d5..4252b0a55 100644 --- a/server/src/codeActions.ts +++ b/server/src/codeActions.ts @@ -277,8 +277,6 @@ let wrapInSome: codeActionExtractor = ({ "but a pattern was expected which matches values of type" ); - console.log({ typ }); - if (typ.trim() === "") { // Type is on the next line typ = (restOfMessage[lineIndexWithType + 1] ?? "").trim();