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

Commitb5bf291

Browse files
dungpaKevinRansom
authored andcommitted
Various fixes for implement interface code fix (dotnet#2120)
* Insert closing brackets if they are missing* Find correct interface identifiers if object expressions are on the same lines with let bindings
1 parent06640a5 commitb5bf291

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

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

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ open Microsoft.FSharp.Compiler.SourceCodeServices
2323
typeinternalInterfaceState=
2424
{ InterfaceData:InterfaceData
2525
EndPosOfWith:pos option
26+
AppendBracketAt:int option
2627
Tokens:FSharpTokenInfo list}
2728

2829
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name="ImplementInterface"); Shared>]
@@ -36,7 +37,7 @@ type internal FSharpImplementInterfaceCodeFixProvider
3637
letfixableDiagnosticIds=["FS0366"]
3738
letchecker= checkerProvider.Checker
3839

39-
letqueryInterfaceState(pos:pos)tokens(ast:Ast.ParsedInput)=
40+
letqueryInterfaceStateappendBracketAt(pos:pos)tokens(ast:Ast.ParsedInput)=
4041
async{
4142
letline= pos.Line-1
4243
letcolumn= pos.Column
@@ -49,7 +50,11 @@ type internal FSharpImplementInterfaceCodeFixProvider
4950
if t.CharClass= FSharpTokenCharKind.Keyword&& t.LeftColumn>= column&& t.TokenName="WITH"then
5051
Some(Pos.fromZ line(t.RightColumn+1))
5152
else None)
52-
return Some{ InterfaceData= iface; EndPosOfWith= endPosOfWidth; Tokens= tokens}
53+
letappendBracketAt=
54+
match iface, appendBracketAtwith
55+
| InterfaceData.ObjExpr_, Some_-> appendBracketAt
56+
|_-> None
57+
return Some{ InterfaceData= iface; EndPosOfWith= endPosOfWidth; AppendBracketAt= appendBracketAt; Tokens= tokens}
5358
}
5459

5560
letgetLineIdent(lineStr:string)=
@@ -75,7 +80,7 @@ type internal FSharpImplementInterfaceCodeFixProvider
7580
// There is no reference point, we indent the content at the start column of the interface
7681
|> Option.defaultValue iface.Range.StartColumn
7782

78-
lethandleImplementInterface(sourceText:SourceText)state displayContext implementedMemberSignatures entity indentSize verboseMode=
83+
letapplyImplementInterface(sourceText:SourceText)state displayContext implementedMemberSignatures entity indentSize verboseMode=
7984
letstartColumn= inferStartColumn indentSize state sourceText
8085
letobjectIdentifier="this"
8186
letdefaultBody="raise (System.NotImplementedException())"
@@ -85,15 +90,21 @@ type internal FSharpImplementInterfaceCodeFixProvider
8590
startColumn indentSize typeParams objectIdentifier defaultBody
8691
displayContext implementedMemberSignatures entity verboseMode
8792
stub.TrimEnd(Environment.NewLine.ToCharArray())
88-
match state.EndPosOfWithwith
89-
| Some pos->
90-
letcurrentPos= sourceText.Lines.[pos.Line-1].Start+ pos.Column
91-
TextChange(TextSpan(currentPos,0), stub)
93+
letstubChange=
94+
match state.EndPosOfWithwith
95+
| Some pos->
96+
letcurrentPos= sourceText.Lines.[pos.Line-1].Start+ pos.Column
97+
TextChange(TextSpan(currentPos,0), stub)
98+
| None->
99+
letrange= state.InterfaceData.Range
100+
letcurrentPos= sourceText.Lines.[range.EndLine-1].Start+ range.EndColumn
101+
TextChange(TextSpan(currentPos,0)," with"+ stub)
102+
match state.AppendBracketAtwith
103+
| Some index->
104+
sourceText.WithChanges(stubChange, TextChange(TextSpan(index,0)," }"))
92105
| None->
93-
letrange= state.InterfaceData.Range
94-
letcurrentPos= sourceText.Lines.[range.EndLine-1].Start+ range.EndColumn
95-
TextChange(TextSpan(currentPos,0)," with"+ stub)
96-
106+
sourceText.WithChanges(stubChange)
107+
97108
letregisterSuggestions(context:CodeFixContext,results:FSharpCheckFileResults,state:InterfaceState,displayContext,entity,indentSize)=
98109
if InterfaceStubGenerator.hasNoInterfaceMember entitythen
99110
()
@@ -116,8 +127,8 @@ type internal FSharpImplementInterfaceCodeFixProvider
116127
results.GetSymbolUseAtLocation(range.EndLine, range.EndColumn, lineStr,[name])
117128
let!implementedMemberSignatures=
118129
InterfaceStubGenerator.getImplementedMemberSignatures getMemberByLocation displayContext state.InterfaceData
119-
lettextChange=handleImplementInterface sourceText state displayContext implementedMemberSignatures entity indentSize verboseMode
120-
return context.Document.WithText(sourceText.WithChanges textChange)
130+
letnewSourceText=applyImplementInterface sourceText state displayContext implementedMemberSignatures entity indentSize verboseMode
131+
return context.Document.WithText(newSourceText)
121132
}|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)),
122133
title)
123134
context.RegisterCodeFix(codeAction, diagnostics)
@@ -146,8 +157,12 @@ type internal FSharpImplementInterfaceCodeFixProvider
146157
// Notice that context.Span doesn't return reliable ranges to find tokens at exact positions.
147158
// That's why we tokenize the line and try to find the last successive identifier token
148159
lettokens= CommonHelpers.tokenizeLine(context.Document.Id, sourceText, context.Span.Start, context.Document.FilePath, defines)
160+
letstartLeftColumn= context.Span.Start- textLine.Start
149161
let rectryFindIdentifierToken acc tokens=
150162
match tokenswith
163+
| t:: remainingTokenswhen t.LeftColumn< startLeftColumn->
164+
// Skip all the tokens starting before the context
165+
tryFindIdentifierToken acc remainingTokens
151166
| t:: remainingTokenswhen t.Tag= FSharpTokenTag.Identifier->
152167
tryFindIdentifierToken(Some t) remainingTokens
153168
| t:: remainingTokenswhen t.Tag= FSharpTokenTag.DOT|| Option.isNone acc->
@@ -158,7 +173,13 @@ type internal FSharpImplementInterfaceCodeFixProvider
158173
| Some token->
159174
letfixupPosition= textLine.Start+ token.RightColumn
160175
letinterfacePos= Pos.fromZ textLine.LineNumber token.RightColumn
161-
let!interfaceState= queryInterfaceState interfacePos tokens parsedInput
176+
// We rely on the observation that the lastChar of the context should be '}' if that character is present
177+
letappendBracketAt=
178+
match sourceText.[context.Span.End-1]with
179+
|'}'-> None
180+
|_->
181+
Some context.Span.End
182+
let!interfaceState= queryInterfaceState appendBracketAt interfacePos tokens parsedInput
162183
letsymbol= CommonHelpers.getSymbolAtPosition(context.Document.Id, sourceText, fixupPosition, context.Document.FilePath, defines, SymbolLookupKind.Fuzzy)
163184
match interfaceState, symbolwith
164185
| Some state, Some symbol->

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp