Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit95fc0b3

Browse files
forkiKevinRansom
authored andcommitted
Propose Uppercase for FS0053 (dotnet#2116)
* Propose Uppercase for FS0053* make ProposeUppercaseLabel code fix work on all symbol uses* cleanup* refactor with asyncMaybe* add ParseAndCheckDocument* refactor ProposeUppercaseLabel
1 parenta7697d6 commit95fc0b3

File tree

9 files changed

+359
-78
lines changed

9 files changed

+359
-78
lines changed

‎src/fsharp/ErrorResolutionHints.fs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ let FilterPredictions (unknownIdent:string) (predictionsF:ErrorLogger.Suggestion
2626
|> Seq.map snd
2727
|> Seq.toList
2828

29+
/// Formats the given predictions according to the error style.
2930
letFormatPredictions errorStyle normalizeF(predictions:(float* string)list)=
3031
match predictionswith
3132
|[]-> System.String.Empty
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
2+
3+
namespacerecMicrosoft.VisualStudio.FSharp.Editor
4+
5+
openSystem.Composition
6+
openSystem.Collections.Immutable
7+
openSystem.Threading.Tasks
8+
openMicrosoft.CodeAnalysis.CodeFixes
9+
openMicrosoft.CodeAnalysis.CodeActions
10+
11+
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name="ProposeUpperCaseLabel"); Shared>]
12+
typeinternalFSharpProposeUpperCaseLabelCodeFixProvider
13+
[<ImportingConstructor>]
14+
(
15+
checkerProvider: FSharpCheckerProvider,
16+
projectInfoManager: ProjectInfoManager
17+
)=
18+
inherit CodeFixProvider()
19+
letfixableDiagnosticIds=["FS0053"]
20+
21+
override__.FixableDiagnosticIds= fixableDiagnosticIds.ToImmutableArray()
22+
23+
override__.RegisterCodeFixesAsync context:Task=
24+
asyncMaybe{
25+
lettextChanger(originalText:string)= originalText.[0].ToString().ToUpper()+ originalText.Substring(1)
26+
let!solutionChanger,originalText= SymbolHelpers.changeAllSymbolReferences(context.Document, context.Span, textChanger, projectInfoManager, checkerProvider.Checker)
27+
lettitle= FSComp.SR.replaceWithSuggestion(textChanger originalText)
28+
context.RegisterCodeFix(
29+
CodeAction.Create(title, solutionChanger, title),
30+
(context.Diagnostics|> Seq.filter(fun x-> fixableDiagnosticIds|> List.contains x.Id)).ToImmutableArray())
31+
}|> Async.ignore|> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)

‎vsintegration/src/FSharp.Editor/CodeFix/ReplaceWithSuggestion.fs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider() =
3737
|> Seq.filter(fun x-> fixableDiagnosticIds|> Set.contains x.Id)
3838
|> Seq.iter(fun diagnostic->
3939
letmessage= diagnostic.GetMessage()
40-
letsplitted= message.Split([|maybeString|], StringSplitOptions.None)
41-
ifsplitted.Length>1then
40+
letparts= message.Split([|maybeString|], StringSplitOptions.None)
41+
ifparts.Length>1then
4242
letsuggestions=
43-
splitted.[1].Split([|' ';'\r';'\n'|], StringSplitOptions.RemoveEmptyEntries)
43+
parts.[1].Split([|' ';'\r';'\n'|], StringSplitOptions.RemoveEmptyEntries)
4444
|> Array.map(fun s-> s.Trim())
4545

4646
letdiagnostics=[| diagnostic|].ToImmutableArray()

‎vsintegration/src/FSharp.Editor/Common/CommonHelpers.fs‎

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,20 @@ module internal Extensions =
416416
try Path.GetFullPath path
417417
with_-> path
418418

419+
typeFSharpCheckerwith
420+
memberthis.ParseAndCheckDocument(document:Document,options:FSharpProjectOptions):Async<(Ast.ParsedInput* FSharpCheckFileResults)option>=
421+
async{
422+
let!cancellationToken= Async.CancellationToken
423+
let!sourceText= document.GetTextAsync()
424+
let!textVersion= document.GetTextVersionAsync(cancellationToken)
425+
let!parseResults,checkFileAnswer= this.ParseAndCheckFileInProject(document.FilePath, textVersion.GetHashCode(), sourceText.ToString(), options)
426+
return
427+
match parseResults.ParseTree, checkFileAnswerwith
428+
|_, FSharpCheckFileAnswer.Aborted
429+
| None,_-> None
430+
| Some parsedInput, FSharpCheckFileAnswer.Succeeded checkResults-> Some(parsedInput, checkResults)
431+
}
432+
419433
typeFSharpSymbolwith
420434
memberthis.IsInternalToProject=
421435
match thiswith
@@ -511,32 +525,4 @@ module internal Extensions =
511525
| GlyphMajor.Error-> Glyph.Error
512526
|_-> Glyph.None
513527

514-
typeAsync<'a>with
515-
/// Creates an asynchronous workflow that runs the asynchronous workflow given as an argument at most once.
516-
/// When the returned workflow is started for the second time, it reuses the result of the previous execution.
517-
static memberCache(input:Async<'T>)=
518-
letagent= MailboxProcessor<AsyncReplyChannel<_>>.Start<|fun agent->
519-
async{
520-
let!replyCh= agent.Receive()
521-
let!res= input
522-
replyCh.Reply res
523-
whiletruedo
524-
let!replyCh= agent.Receive()
525-
replyCh.Reply res
526-
}
527-
async{return! agent.PostAndAsyncReply id}
528-
529-
static member inlineMap(f:'a->'b)(input:Async<'a>):Async<'b>=
530-
async{
531-
let!result= input
532-
return f result
533-
}
534-
535-
typeAsyncBuilderwith
536-
member__.Bind(computation:System.Threading.Tasks.Task<'a>,binder:'a->Async<'b>):Async<'b>=
537-
async{
538-
let!a= Async.AwaitTask computation
539-
return! binder a
540-
}
541-
542-
member__.ReturnFrom(computation:System.Threading.Tasks.Task<'a>):Async<'a>= Async.AwaitTask computation
528+

‎vsintegration/src/FSharp.Editor/Common/CommonRoslynHelpers.fs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,4 @@ module internal RoslynExtensions =
9494
memberthis.GetDependentProjects()=
9595
[for projectin this.Solution.Projectsdo
9696
if project.ProjectReferences|> Seq.exists(fun ref-> ref.ProjectId= this.Id)then
97-
yield project]
97+
yield project]

‎vsintegration/src/FSharp.Editor/Common/Pervasive.fs‎

Lines changed: 195 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[<AutoOpen>]
2-
moduleMicrosoft.VisualStudio.FSharp.Pervasive
2+
moduleMicrosoft.VisualStudio.FSharp.Editor.Pervasive
33

44
openSystem
5+
openSystem.Diagnostics
56

67
[<RequireQualifiedAccess>]
78
moduleString=
@@ -24,3 +25,196 @@ type System.IServiceProvider with
2425
memberx.GetService<'T>()= x.GetService(typeof<'T>):?> 'T
2526
memberx.GetService<'S,'T>()= x.GetService(typeof<'S>):?> 'T
2627

28+
[<Sealed>]
29+
typeMaybeBuilder()=
30+
// 'T -> M<'T>
31+
[<DebuggerStepThrough>]
32+
member inline__.Return value:'T option=
33+
Some value
34+
35+
// M<'T> -> M<'T>
36+
[<DebuggerStepThrough>]
37+
member inline__.ReturnFrom value:'T option=
38+
value
39+
40+
// unit -> M<'T>
41+
[<DebuggerStepThrough>]
42+
member inline__.Zero():unit option=
43+
Some()// TODO: Should this be None?
44+
45+
// (unit -> M<'T>) -> M<'T>
46+
[<DebuggerStepThrough>]
47+
member__.Delay(f:unit->'T option):'T option=
48+
f()
49+
50+
// M<'T> -> M<'T> -> M<'T>
51+
// or
52+
// M<unit> -> M<'T> -> M<'T>
53+
[<DebuggerStepThrough>]
54+
member inline__.Combine(r1,r2:'T option):'T option=
55+
match r1with
56+
| None->
57+
None
58+
| Some()->
59+
r2
60+
61+
// M<'T> * ('T -> M<'U>) -> M<'U>
62+
[<DebuggerStepThrough>]
63+
member inline__.Bind(value,f:'T->'U option):'U option=
64+
Option.bind f value
65+
66+
// 'T * ('T -> M<'U>) -> M<'U> when 'U :> IDisposable
67+
[<DebuggerStepThrough>]
68+
member__.Using(resource:('T:> System.IDisposable),body:_->_ option):_ option=
69+
try body resource
70+
finally
71+
ifnot<| obj.ReferenceEquals(null, box resource)then
72+
resource.Dispose()
73+
74+
// (unit -> bool) * M<'T> -> M<'T>
75+
[<DebuggerStepThrough>]
76+
memberx.While(guard,body:_ option):_ option=
77+
if guard()then
78+
// OPTIMIZE: This could be simplified so we don't need to make calls to Bind and While.
79+
x.Bind(body,(fun()-> x.While(guard, body)))
80+
else
81+
x.Zero()
82+
83+
// seq<'T> * ('T -> M<'U>) -> M<'U>
84+
// or
85+
// seq<'T> * ('T -> M<'U>) -> seq<M<'U>>
86+
[<DebuggerStepThrough>]
87+
memberx.For(sequence:seq<_>,body:'T->unit option):_ option=
88+
// OPTIMIZE: This could be simplified so we don't need to make calls to Using, While, Delay.
89+
x.Using(sequence.GetEnumerator(),fun enum->
90+
x.While(
91+
enum.MoveNext,
92+
x.Delay(fun()->
93+
bodyenum.Current)))
94+
95+
letmaybe= MaybeBuilder()
96+
97+
[<Sealed>]
98+
typeAsyncMaybeBuilder()=
99+
[<DebuggerStepThrough>]
100+
member__.Return value:Async<'Toption>= Some value|> async.Return
101+
102+
[<DebuggerStepThrough>]
103+
member__.ReturnFrom value:Async<'Toption>= value
104+
105+
[<DebuggerStepThrough>]
106+
member__.ReturnFrom(value:'T option):Async<'Toption>= async.Return value
107+
108+
[<DebuggerStepThrough>]
109+
member__.Zero():Async<unitoption>=
110+
Some()|> async.Return
111+
112+
[<DebuggerStepThrough>]
113+
member__.Delay(f:unit->Async<'Toption>):Async<'Toption>= f()
114+
115+
[<DebuggerStepThrough>]
116+
member__.Combine(r1,r2:Async<'Toption>):Async<'Toption>=
117+
async{
118+
let!r1'= r1
119+
match r1'with
120+
| None->return None
121+
| Some()->return! r2
122+
}
123+
124+
[<DebuggerStepThrough>]
125+
member__.Bind(value:Async<'Toption>,f:'T->Async<'Uoption>):Async<'Uoption>=
126+
async{
127+
let!value'= value
128+
match value'with
129+
| None->return None
130+
| Some result->return! f result
131+
}
132+
133+
[<DebuggerStepThrough>]
134+
member__.Bind(value:System.Threading.Tasks.Task<'T>,f:'T->Async<'Uoption>):Async<'Uoption>=
135+
async{
136+
let!value'= Async.AwaitTask value
137+
return! f value'
138+
}
139+
140+
[<DebuggerStepThrough>]
141+
member__.Bind(value:'T option,f:'T->Async<'Uoption>):Async<'Uoption>=
142+
async{
143+
match valuewith
144+
| None->return None
145+
| Some result->return! f result
146+
}
147+
148+
[<DebuggerStepThrough>]
149+
member__.Using(resource:('T:> IDisposable),body:_->Async<_option>):Async<_option>=
150+
try body resource
151+
finallyifnot(isNull resource)then resource.Dispose()
152+
153+
[<DebuggerStepThrough>]
154+
memberx.While(guard,body:Async<_option>):Async<_option>=
155+
if guard()then
156+
x.Bind(body,(fun()-> x.While(guard, body)))
157+
else
158+
x.Zero()
159+
160+
[<DebuggerStepThrough>]
161+
memberx.For(sequence:seq<_>,body:'T->Async<unitoption>):Async<_option>=
162+
x.Using(sequence.GetEnumerator(),fun enum->
163+
x.While(enum.MoveNext, x.Delay(fun()-> bodyenum.Current)))
164+
165+
[<DebuggerStepThrough>]
166+
member inline__.TryWith(computation:Async<'Toption>,catchHandler:exn->Async<'Toption>):Async<'Toption>=
167+
async.TryWith(computation, catchHandler)
168+
169+
[<DebuggerStepThrough>]
170+
member inline__.TryFinally(computation:Async<'Toption>,compensation:unit->unit):Async<'Toption>=
171+
async.TryFinally(computation, compensation)
172+
173+
letasyncMaybe= AsyncMaybeBuilder()
174+
175+
let inlineliftAsync(computation:Async<'T>):Async<'Toption>=
176+
async{
177+
let!a= computation
178+
return Some a
179+
}
180+
181+
moduleAsync=
182+
letmap(f:'T->'U)(a:Async<'T>):Async<'U>=
183+
async{
184+
let!a= a
185+
return f a
186+
}
187+
188+
letignore(a:Async<'T>):Async<unit>=
189+
async{
190+
let!_= a
191+
return()
192+
}
193+
194+
/// Creates an asynchronous workflow that runs the asynchronous workflow given as an argument at most once.
195+
/// When the returned workflow is started for the second time, it reuses the result of the previous execution.
196+
letcache(input:Async<'T>)=
197+
letagent= MailboxProcessor<AsyncReplyChannel<_>>.Start<|fun agent->
198+
async{
199+
let!replyCh= agent.Receive()
200+
let!res= input
201+
replyCh.Reply res
202+
whiletruedo
203+
let!replyCh= agent.Receive()
204+
replyCh.Reply res
205+
}
206+
async{return! agent.PostAndAsyncReply id}
207+
208+
typeAsyncBuilderwith
209+
member__.Bind(computation:System.Threading.Tasks.Task<'a>,binder:'a->Async<'b>):Async<'b>=
210+
async{
211+
let!a= Async.AwaitTask computation
212+
return! binder a
213+
}
214+
215+
member__.ReturnFrom(computation:System.Threading.Tasks.Task<'a>):Async<'a>= Async.AwaitTask computation
216+
217+
218+
moduleOption=
219+
letguard(x:bool):Option<unit>=
220+
if xthen Some()else None

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp