Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddExplicitReturnType refactoring #16077

Merged
merged 63 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
e27012e
First Draft for AddExplicitReturnType (#15562) with exploration test …
SebastianAtWork Oct 4, 2023
b0fbe67
Added Workspace handling and some debug stuff #15562
SebastianAtWork Oct 5, 2023
81d8f0e
Added One Way of getting the changed Solution for ExplicitReturnTypes…
SebastianAtWork Oct 7, 2023
25b901e
added language resource files (not translated) #15562
SebastianAtWork Oct 8, 2023
c9baeda
refactor: Create test context and check return type
SebastianAtWork Oct 19, 2023
42d67f5
refactor: Add explicit return type in FSharp.Editor.Tests/Refactors/A…
SebastianAtWork Oct 19, 2023
493b374
feat: Add function to get return type of symbol
SebastianAtWork Oct 19, 2023
12d76d4
refactor: Remove explicit return type annotation
SebastianAtWork Oct 20, 2023
b22a519
chore: committed resources
SebastianAtWork Oct 20, 2023
a14c048
* test(FSharp.Editor.Tests): finally got a working test for remove e…
SebastianAtWork Oct 23, 2023
7b31775
🚀feat(tests) add F# editor refactoring tests
SebastianAtWork Oct 24, 2023
83bfb1e
fix: formatting
SebastianAtWork Oct 24, 2023
da2dc25
* refactor(FSharp.Editor): improve explicit return type removal
SebastianAtWork Oct 24, 2023
7c4f039
* feat(FSharp.Editor): add RangeOfReturnTypeDefinition and refactor m…
SebastianAtWork Oct 25, 2023
9e31a4e
* refactor(FSharp.Editor.Tests): simplify and improve test code reada…
SebastianAtWork Oct 25, 2023
1df0308
fix: remove debug lines
SebastianAtWork Oct 25, 2023
fefe14b
* refactor(FSharp.Editor.Tests): improve test method names and assert…
SebastianAtWork Oct 29, 2023
7cf8ab0
* feat(FSharp.Editor): add InternalOptionBuilder module
SebastianAtWork Oct 29, 2023
0c306a3
* refactor(FSharp.Editor): simplify async tasks in AddExplicitReturnT…
SebastianAtWork Oct 30, 2023
8335c0b
* feat(FSharp.Editor): update condition for return type hint presence…
SebastianAtWork Oct 30, 2023
0918cfb
* feat(FSharp.Editor.Tests): add new test cases for AddExplicitReturn…
SebastianAtWork Nov 1, 2023
0a8c952
* feat(FSharp.Editor.Tests): add AsyncBugReproduction.fs to test suite
SebastianAtWork Nov 2, 2023
ac3cb24
bug: boiled bug down more
SebastianAtWork Nov 2, 2023
168dc63
* feat(FSharpParseFileResults.fs): add RangeOfReturnTypeDefinition me…
SebastianAtWork Nov 2, 2023
5978ad5
* refactor(FSharp.Editor.Tests): remove async tasks from test cases a…
SebastianAtWork Nov 7, 2023
c6ea3fc
* refactor(FSharp.Editor): simplify refactoring process in AddExplici…
SebastianAtWork Nov 7, 2023
a135896
remove RemoveExplicitReturnType and save for a different PR
SebastianAtWork Nov 7, 2023
e4f849c
test: fixed test formatting
SebastianAtWork Nov 13, 2023
99e3686
* refactor(FSharp.Editor): remove InternalOptionBuilder.fs and update…
SebastianAtWork Nov 13, 2023
7274f3e
* refactor(FSharp.Editor.Tests): rename AddExplicitReturnType.fs to A…
SebastianAtWork Nov 13, 2023
ec5ab97
* refactor(FSharp.Editor): remove unused imports in AddExplicitReturn…
SebastianAtWork Nov 13, 2023
30b5fe7
* refactor(FSharpParseFileResults.fs, FSharpParseFileResults.fsi, Ref…
SebastianAtWork Nov 13, 2023
a3d2ce2
* feat(FSharp.Editor.Tests): add GetLastDocument method in RoslynHelp…
SebastianAtWork Nov 14, 2023
f8bfd0c
* refactor(RefactorTestFramework.fs): simplify TestContext type and r…
SebastianAtWork Nov 15, 2023
3a2257f
* style: add space after colon in type annotations in AddExplicitRetu…
SebastianAtWork Nov 15, 2023
1d24e5a
* refactor(AddExplicitReturnType.fs): remove unused CancellationToken…
SebastianAtWork Nov 16, 2023
c700bf8
* feat(FSharp.Editor): add checks for function or value names in AddE…
SebastianAtWork Nov 20, 2023
9bb4545
* refactor(AddExplicitReturnTypeTests.fs): remove unused System.Linq …
SebastianAtWork Nov 21, 2023
867803d
* refactor(RefactorTestFramework.fs): remove unused import Microsoft.…
SebastianAtWork Nov 21, 2023
77987ca
I dont know this file type
SebastianAtWork Nov 21, 2023
2a6e573
* refactor(AddExplicitReturnType.fs): simplify match expressions and …
SebastianAtWork Nov 21, 2023
5d004eb
fixed: AddExplicitReturnTypeTests
SebastianAtWork Dec 1, 2023
3edc9d0
Automated command ran: fantomas
github-actions[bot] Dec 1, 2023
555ff74
Merge branch 'dotnet:main' into features/codefix-return-type
SebastianAtWork Dec 1, 2023
e59af47
* fix: add space before equals sign in type annotations in AddExplici…
SebastianAtWork Dec 2, 2023
4c48771
* feat(AddExplicitReturnType.fs): add support for generic return type…
SebastianAtWork Dec 2, 2023
79603fb
* refactor(AddExplicitReturnType.fs): improve inferredType calculatio…
SebastianAtWork Dec 2, 2023
d0940c2
fix: remove strange artifact
SebastianAtWork Dec 2, 2023
81623d5
* refactor(FSharp.Editor): rename 'AddExplicitReturnTypeAnnotation' t…
SebastianAtWork Dec 2, 2023
ca88258
* refactor(FSharp.Editor): simplify CancellationToken usage in TestCo…
SebastianAtWork Dec 2, 2023
2590310
Merge branch 'dotnet:main' into features/codefix-return-type
SebastianAtWork Dec 6, 2023
7283db8
refactor: Improve code readability and performance
SebastianAtWork Dec 6, 2023
0a5a193
refactor: Improve code readability and performance
SebastianAtWork Dec 6, 2023
e7d8114
Merge branch 'dotnet:main' into features/codefix-return-type
SebastianAtWork Dec 13, 2023
d9310a3
refactor: Refactored AddExplicitReturnType.fs and AddExplicitReturnTy…
SebastianAtWork Dec 13, 2023
e51805d
Merge branch 'dotnet:main' into features/codefix-return-type
SebastianAtWork Dec 15, 2023
696b930
refactor: Simplify AddExplicitReturnType logic
SebastianAtWork Dec 15, 2023
323c863
refactor: Add explicit return type to sum function
SebastianAtWork Dec 15, 2023
6fb62df
tests: Added new special test cases for already existing opens
SebastianAtWork Dec 15, 2023
8cf85ec
refactor: Update return type annotation in localization files
SebastianAtWork Dec 16, 2023
3a7eac4
refactor: Rename AddExplicitReturnType to AddReturnType
SebastianAtWork Dec 16, 2023
b4ea8b9
Merge branch 'dotnet:main' into features/codefix-return-type
SebastianAtWork Dec 16, 2023
14c2acc
Merge branch 'main' into features/codefix-return-type
SebastianAtWork Dec 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
<Compile Include="Commands\HelpContextService.fs" />
<Compile Include="Commands\FsiCommandService.fs" />
<Compile Include="Commands\XmlDocCommandService.fs" />
<Compile Include="Refactor\AddReturnType.fs" />
<Compile Include="Refactor\ChangeTypeofWithNameToNameofExpression.fs" />
<Compile Include="Refactor\AddExplicitTypeToParameter.fs" />
<Compile Include="Refactor\ChangeDerefToValueRefactoring.fs" />
Expand Down
3 changes: 3 additions & 0 deletions vsintegration/src/FSharp.Editor/FSharp.Editor.resx
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ Use live (unsaved) buffers for analysis</value>
<data name="ConvertCSharpUsingToFSharpOpen" xml:space="preserve">
<value>Convert C# 'using' to F# 'open'</value>
</data>
<data name="AddReturnTypeAnnotation" xml:space="preserve">
<value>Add return type annotation</value>
</data>
<data name="RemoveUnnecessaryParentheses" xml:space="preserve">
<value>Remove unnecessary parentheses</value>
</data>
Expand Down
118 changes: 118 additions & 0 deletions vsintegration/src/FSharp.Editor/Refactor/AddReturnType.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
namespace Microsoft.VisualStudio.FSharp.Editor

open System.Composition
open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.Symbols
open FSharp.Compiler.Text

open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.CodeRefactorings
open Microsoft.CodeAnalysis.CodeActions
open CancellableTasks

[<ExportCodeRefactoringProvider(FSharpConstants.FSharpLanguageName, Name = "AddReturnType"); Shared>]
type internal AddReturnType [<ImportingConstructor>] () =
inherit CodeRefactoringProvider()

static member isValidMethodWithoutTypeAnnotation
(symbolUse: FSharpSymbolUse)
(parseFileResults: FSharpParseFileResults)
(funcOrValue: FSharpMemberOrFunctionOrValue)
=
let typeAnnotationRange =
parseFileResults.TryRangeOfReturnTypeHint(symbolUse.Range.Start, false)

let res =
funcOrValue.CompiledName = funcOrValue.DisplayName
&& funcOrValue.IsFunction
&& not (parseFileResults.IsBindingALambdaAtPosition symbolUse.Range.Start)
&& not (funcOrValue.ReturnParameter.Type.IsUnresolved)
&& not (parseFileResults.IsTypeAnnotationGivenAtPosition symbolUse.Range.Start)
&& not typeAnnotationRange.IsNone

match (res, typeAnnotationRange) with
| (true, Some tr) -> Some(funcOrValue, tr)
| (_, _) -> None

static member refactor
(context: CodeRefactoringContext)
(memberFunc: FSharpMemberOrFunctionOrValue, typeRange: Range, symbolUse: FSharpSymbolUse)
=
let title = SR.AddReturnTypeAnnotation()

let getChangedText (sourceText: SourceText) =
let returnType = memberFunc.ReturnParameter.Type

let inferredType =
let res = returnType.Format symbolUse.DisplayContext

if returnType.HasTypeDefinition then
res
else
$"({res})".Replace(" ", "")

let textSpan = RoslynHelpers.FSharpRangeToTextSpan(sourceText, typeRange)
let textChange = TextChange(textSpan, $": {inferredType} ")
sourceText.WithChanges(textChange)

let codeActionFunc =
cancellableTask {
let! cancellationToken = CancellableTask.getCancellationToken ()
let! sourceText = context.Document.GetTextAsync(cancellationToken)
let changedText = getChangedText sourceText

let newDocument = context.Document.WithText(changedText)
return newDocument
}

let codeAction = CodeAction.Create(title, codeActionFunc, title)

do context.RegisterRefactoring(codeAction)

static member ofFSharpMemberOrFunctionOrValue(symbol: FSharpSymbol) =
match symbol with
| :? FSharpMemberOrFunctionOrValue as v -> Some v
| _ -> None

override _.ComputeRefactoringsAsync context =
cancellableTask {
let document = context.Document
let position = context.Span.Start
let! sourceText = document.GetTextAsync()
let textLine = sourceText.Lines.GetLineFromPosition position
let textLinePos = sourceText.Lines.GetLinePosition position
let fcsTextLineNumber = Line.fromZ textLinePos.Line

let! lexerSymbol =
document.TryFindFSharpLexerSymbolAsync(position, SymbolLookupKind.Greedy, false, false, nameof (AddReturnType))

let! (parseFileResults, checkFileResults) = document.GetFSharpParseAndCheckResultsAsync(nameof (AddReturnType))

let symbolUseOpt =
lexerSymbol
|> Option.bind (fun lexer ->
checkFileResults.GetSymbolUseAtLocation(
fcsTextLineNumber,
lexer.Ident.idRange.EndColumn,
textLine.ToString(),
lexer.FullIsland
))

let memberFuncOpt =
symbolUseOpt
|> Option.bind (fun sym -> sym.Symbol |> AddReturnType.ofFSharpMemberOrFunctionOrValue)

match (symbolUseOpt, memberFuncOpt) with
| (Some symbolUse, Some memberFunc) ->
let isValidMethod =
memberFunc
|> AddReturnType.isValidMethodWithoutTypeAnnotation symbolUse parseFileResults

match isValidMethod with
| Some(memberFunc, typeRange) -> do AddReturnType.refactor context (memberFunc, typeRange, symbolUse)
| None -> ()
| _ -> ()

return ()
}
|> CancellableTask.startAsTask context.CancellationToken
5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vsintegration/src/FSharp.Editor/xlf/FSharp.Editor.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
</PropertyGroup>

<ItemGroup>

<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Expand Down Expand Up @@ -71,6 +72,8 @@
<Compile Include="CodeFixes\ConvertCSharpUsingToFSharpOpenTests.fs" />
<Compile Include="CodeFixes\ReplaceWithSuggestionTests.fs" />
<Compile Include="CodeFixes\RemoveUnnecessaryParenthesesTests.fs" />
<Compile Include="Refactors\RefactorTestFramework.fs" />
<Compile Include="Refactors\AddReturnTypeTests.fs" />
<Compile Include="Hints\HintTestFramework.fs" />
<Compile Include="Hints\OptionParserTests.fs" />
<Compile Include="Hints\InlineParameterNameHintTests.fs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ type RoslynTestHelpers private () =
let document = project.Documents |> Seq.exactlyOne
document

static member GetLastDocument(solution: Solution) =
let project = solution.Projects |> Seq.exactlyOne
let document = project.Documents |> Seq.last
document

static member CreateSolution(syntheticProject: SyntheticProject) =

let checker = syntheticProject.SaveAndCheck()
Expand Down
Loading