Skip to content

Commit 983bdd7

Browse files
zthcristianoc
authored andcommitted
add code action for unwrapping optionals
1 parent cd73ff9 commit 983bdd7

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

server/src/codeActions.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export let findCodeActionsInDiagnosticsMessage = ({
100100
applyUncurried,
101101
simpleAddMissingCases,
102102
simpleWrapOptionalWithSome,
103+
simpleUnwrapOptional,
103104
];
104105

105106
for (let action of actions) {
@@ -607,3 +608,89 @@ let simpleWrapOptionalWithSome: codeActionExtractor = ({
607608

608609
return false;
609610
};
611+
612+
let simpleUnwrapOptional: codeActionExtractor = ({
613+
line,
614+
codeActions,
615+
file,
616+
range,
617+
diagnostic,
618+
array,
619+
index,
620+
}) => {
621+
// Examples:
622+
//
623+
// 47 │
624+
// 48 │ let as_ = {
625+
// 49 │ someProp: optional,
626+
// 50 │ another: Some("123"),
627+
// 51 │ }
628+
629+
// This has type: option<string>
630+
// Somewhere wanted: string
631+
632+
if (line.startsWith("This has type: option<")) {
633+
let thisHasTypeLine = line;
634+
let hasTypeText = thisHasTypeLine.split("This has type: option<")[1].trim();
635+
// Remove ending `>` so we can compare the underlying types
636+
hasTypeText = hasTypeText.slice(0, hasTypeText.length - 1);
637+
638+
let somewhereWantedLine = array[index + 1];
639+
let somewhereWantedText = somewhereWantedLine
640+
.split("Somewhere wanted: ")[1]
641+
.trim();
642+
643+
// We only trigger the code action if the thing that's already there is the
644+
// exact same type.
645+
if (hasTypeText === somewhereWantedText) {
646+
codeActions[file] = codeActions[file] || [];
647+
648+
// We can figure out default values for primitives etc.
649+
let defaultValue = "assert false";
650+
651+
switch (somewhereWantedText) {
652+
case "string": {
653+
defaultValue = `"-"`;
654+
break;
655+
}
656+
case "bool": {
657+
defaultValue = `false`;
658+
break;
659+
}
660+
case "int": {
661+
defaultValue = `-1`;
662+
break;
663+
}
664+
case "float": {
665+
defaultValue = `-1.`;
666+
break;
667+
}
668+
}
669+
670+
let codeAction: p.CodeAction = {
671+
title: `Unwrap optional value`,
672+
edit: {
673+
changes: {
674+
[file]: wrapRangeInText(
675+
range,
676+
"switch ",
677+
` { | None => ${defaultValue} | Some(v) => v }`
678+
),
679+
},
680+
},
681+
diagnostics: [diagnostic],
682+
kind: p.CodeActionKind.QuickFix,
683+
isPreferred: true,
684+
};
685+
686+
codeActions[file].push({
687+
range,
688+
codeAction,
689+
});
690+
691+
return true;
692+
}
693+
}
694+
695+
return false;
696+
};

0 commit comments

Comments
 (0)