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

Commitf50a2dd

Browse files
vasily-kirichenkoKevinRansom
authored andcommitted
Simplify Name analyzer and code fix (dotnet#2226)
* add RemoveQualificationDiagnosticAnalyzer skeleton* diagnose all symbols as unnecessary* exclude symbol uses from definition* add GetVisibleNamespacesAndModulesAtPoint* return ModuleOrNamespaceRef directly* call GetVisibleNamespacesAndModulesAtPoint in the analyzer* the analyzer works* add Code Fix* remove plid from code fix title* use SymbolUse.Symbol.Item to check if it can be resolved* it works* fix many bugs* Fix resources* fixed: the diagnostic is not returned for single-part plid
1 parent24e3547 commitf50a2dd

File tree

12 files changed

+214
-1
lines changed

12 files changed

+214
-1
lines changed

‎src/fsharp/FSStrings.resx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1092,4 +1092,4 @@
10921092
<dataname="TargetInvocationExceptionWrapper"xml:space="preserve">
10931093
<value>internal error: {0}</value>
10941094
</data>
1095-
</root>
1095+
</root>

‎src/fsharp/NameResolution.fs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3890,3 +3890,17 @@ and ResolvePartialLongIdentToClassOrRecdFieldsImpl (ncenv: NameResolver) (nenv:
38903890
|> List.map Item.RecdField
38913891
|_->[]
38923892
modsOrNs@ qualifiedFields
3893+
3894+
letGetVisibleNamespacesAndModulesAtPoint(ncenv:NameResolver)(nenv:NameResolutionEnv)m ad=
3895+
letilTyconNames=
3896+
nenv.TyconsByAccessNames(FullyQualifiedFlag.OpenQualified).Values
3897+
|> List.choose(fun tyconRef->if tyconRef.IsILTyconthen Some tyconRef.DisplayNameelse None)
3898+
|> Set.ofList
3899+
3900+
nenv.ModulesAndNamespaces(FullyQualifiedFlag.OpenQualified)
3901+
|> NameMultiMap.range
3902+
|> List.filter(fun x->
3903+
letdemangledName= x.DemangledModuleOrNamespaceName
3904+
IsInterestingModuleName demangledName&& notFakeContainerModule ilTyconNames demangledName
3905+
&& EntityRefContainsSomethingAccessible ncenv m ad x
3906+
&&not(IsTyconUnseen ad ncenv.g ncenv.amap m x))

‎src/fsharp/NameResolution.fsi‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,5 @@ type ResolveCompletionTargets =
417417

418418
/// Resolve a (possibly incomplete) long identifier to a set of possible resolutions, qualified by type.
419419
valResolveCompletionsInType:NameResolver->NameResolutionEnv->ResolveCompletionTargets->Range.range->AccessorDomain->bool->TType->Item list
420+
421+
valGetVisibleNamespacesAndModulesAtPoint:NameResolver->NameResolutionEnv->range->AccessorDomain->ModuleOrNamespaceRef list

‎src/fsharp/vs/service.fs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,17 @@ type TypeCheckInfo
11121112
else
11131113
items
11141114

1115+
11151116
static letkeywordTypes= Lexhelp.Keywords.keywordTypes
11161117

1118+
memberx.GetVisibleNamespacesAndModulesAtPosition(cursorPos:pos):ModuleOrNamespaceRef list=
1119+
let(nenv,ad),m= GetBestEnvForPos cursorPos
1120+
NameResolution.GetVisibleNamespacesAndModulesAtPoint ncenv nenv m ad
1121+
1122+
memberx.IsRelativeNameResolvable(cursorPos:pos,plid:string list,item:Item):bool=
1123+
letitems,_,_= GetEnvironmentLookupResolutions(cursorPos, plid, TypeNameResolutionFlag.ResolveTypeNamesToTypeRefs,true)
1124+
items|> List.exists(ItemsAreEffectivelyEqual g item)
1125+
11171126
/// Get the auto-complete items at a location
11181127
memberx.GetDeclarations(parseResultsOpt,line,lineStr,colAtEndOfNamesAndResidue,qualifyingNames,partialName,hasTextChangedSinceLastTypecheck)=
11191128
letisInterfaceFile= SourceFileImpl.IsInterfaceFile mainInputFileName
@@ -2041,6 +2050,11 @@ type FSharpCheckFileResults(errors: FSharpErrorInfo[], scopeOptX: TypeCheckInfo
20412050
if itemOcc<> ItemOccurence.RelatedTextthen
20422051
yield FSharpSymbolUse(scope.TcGlobals, denv, symbol, itemOcc, m)|])
20432052

2053+
memberinfo.GetVisibleNamespacesAndModulesAtPoint(pos:pos):Async<ModuleOrNamespaceRef[]>=
2054+
reactorOp"GetDeclarations"[||](fun scope-> scope.GetVisibleNamespacesAndModulesAtPosition(pos)|> List.toArray)
2055+
2056+
memberinfo.IsRelativeNameResolvable(pos:pos,plid:string list,item:Item):Async<bool>=
2057+
reactorOp"IsRelativeNameResolvable"true(fun scope-> scope.IsRelativeNameResolvable(pos, plid, item))
20442058

20452059
//----------------------------------------------------------------------------
20462060
// BackgroundCompiler

‎src/fsharp/vs/service.fsi‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,9 @@ type internal FSharpCheckFileResults =
283283
/// Get the textual usages that resolved to the given symbol throughout the file
284284
member GetUsesOfSymbolInFile: symbol:FSharpSymbol-> Async<FSharpSymbolUse[]>
285285

286+
member GetVisibleNamespacesAndModulesAtPoint: pos-> Async<Tast.ModuleOrNamespaceRef[]>
286287

288+
member IsRelativeNameResolvable: cursorPos: pos* plid: string list* item: Item-> Async<bool>
287289

288290
/// A handle to the results of CheckFileInProject.
289291
[<Sealed>]
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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
8+
openSystem.Threading.Tasks
9+
10+
openMicrosoft.CodeAnalysis
11+
openMicrosoft.CodeAnalysis.Diagnostics
12+
openMicrosoft.CodeAnalysis.Text
13+
openMicrosoft.CodeAnalysis.CodeFixes
14+
openMicrosoft.CodeAnalysis.CodeActions
15+
16+
[<ExportCodeFixProvider(FSharpCommonConstants.FSharpLanguageName, Name= PredefinedCodeFixProviderNames.SimplifyNames); Shared>]
17+
typeinternalFSharpSimplifyNameCodeFixProvider()=
18+
inherit CodeFixProvider()
19+
letfixableDiagnosticId= IDEDiagnosticIds.SimplifyNamesDiagnosticId
20+
21+
letcreateCodeFix(title:string,context:CodeFixContext,textChange:TextChange)=
22+
CodeAction.Create(
23+
title,
24+
(fun(cancellationToken: CancellationToken)->
25+
async{
26+
let!sourceText= context.Document.GetTextAsync()
27+
return context.Document.WithText(sourceText.WithChanges(textChange))
28+
}|> CommonRoslynHelpers.StartAsyncAsTask(cancellationToken)),
29+
title)
30+
31+
override__.FixableDiagnosticIds= ImmutableArray.Create(fixableDiagnosticId)
32+
33+
override__.RegisterCodeFixesAsync(context:CodeFixContext):Task=
34+
async{
35+
for diagnosticin context.Diagnostics|> Seq.filter(fun x-> x.Id= fixableDiagnosticId)do
36+
lettitle=
37+
match diagnostic.Properties.TryGetValue(SimplifyNameDiagnosticAnalyzer.LongIdentPropertyKey)with
38+
|true, longIdent-> sprintf"%s '%s'" SR.SimplifyName.Value longIdent
39+
|_-> SR.SimplifyName.Value
40+
41+
context.RegisterCodeFix(
42+
createCodeFix(title, context, TextChange(context.Span,"")),
43+
ImmutableArray.Create(diagnostic))
44+
}
45+
|> CommonRoslynHelpers.StartAsyncUnitAsTask(context.CancellationToken)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ module internal CommonRoslynHelpers =
206206
| Private-> Glyph.ClassPrivate
207207
|_-> Glyph.None
208208

209+
letRangeToLocation(r:range,sourceText:SourceText,filePath:string):Location=
210+
letlinePositionSpan= LinePositionSpan(LinePosition(Line.toZ r.StartLine, r.StartColumn), LinePosition(Line.toZ r.EndLine, r.EndColumn))
211+
lettextSpan= sourceText.Lines.GetTextSpan linePositionSpan
212+
Location.Create(filePath, textSpan, linePositionSpan)
213+
209214
[<AutoOpen>]
210215
moduleinternalRoslynExtensions=
211216
typeProjectwith
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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
6+
openSystem.Composition
7+
openSystem.Collections.Immutable
8+
openSystem.Threading
9+
openSystem.Threading.Tasks
10+
openSystem.Runtime.CompilerServices
11+
12+
openMicrosoft.CodeAnalysis
13+
openMicrosoft.CodeAnalysis.Diagnostics
14+
openMicrosoft.FSharp.Compiler
15+
openMicrosoft.FSharp.Compiler.Range
16+
openMicrosoft.FSharp.Compiler.SourceCodeServices
17+
18+
openMicrosoft.VisualStudio.FSharp.LanguageService
19+
20+
typeprivateLineHash= int
21+
22+
[<DiagnosticAnalyzer(FSharpCommonConstants.FSharpLanguageName)>]
23+
typeinternalSimplifyNameDiagnosticAnalyzer()=
24+
inherit DocumentDiagnosticAnalyzer()
25+
26+
letgetProjectInfoManager(document:Document)= document.Project.Solution.Workspace.Services.GetService<FSharpCheckerWorkspaceService>().ProjectInfoManager
27+
letgetChecker(document:Document)= document.Project.Solution.Workspace.Services.GetService<FSharpCheckerWorkspaceService>().Checker
28+
letgetPlidLength(plid:string list)=(plid|> List.sumBy String.length)+ plid.Length
29+
30+
static letDescriptor=
31+
DiagnosticDescriptor(
32+
IDEDiagnosticIds.SimplifyNamesDiagnosticId,
33+
SR.SimplifyName.Value,
34+
SR.NameCanBeSimplified.Value,
35+
SR.StyleCategory.Value,
36+
DiagnosticSeverity.Hidden,
37+
true,
38+
"",
39+
"",
40+
DiagnosticCustomTags.Unnecessary)
41+
42+
static memberLongIdentPropertyKey="FullName"
43+
44+
override__.SupportedDiagnostics= ImmutableArray.Create Descriptor
45+
46+
overridethis.AnalyzeSyntaxAsync(document:Document,cancellationToken:CancellationToken)=
47+
asyncMaybe{
48+
match getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document)with
49+
| Some options->
50+
let!sourceText= document.GetTextAsync()
51+
letchecker= getChecker document
52+
let!_,checkResults= checker.ParseAndCheckDocument(document, options, sourceText)
53+
let!symbolUses= checkResults.GetAllUsesOfAllSymbolsInFile()|> liftAsync
54+
let mutableresult= ResizeArray()
55+
letsymbolUses=
56+
symbolUses
57+
|> Array.Parallel.map(fun symbolUse->
58+
letlineStr= sourceText.Lines.[Line.toZ symbolUse.RangeAlternate.StartLine].ToString()
59+
// for `System.DateTime.Now` it returns ([|"System"; "DateTime"|], "Now")
60+
letplid,name= QuickParse.GetPartialLongNameEx(lineStr, symbolUse.RangeAlternate.EndColumn-1)
61+
// `symbolUse.RangeAlternate.Start` does not point to the start of plid, it points to start of `name`,
62+
// so we have to calculate plid's start ourselves.
63+
letplidStartCol= symbolUse.RangeAlternate.EndColumn- name.Length-(getPlidLength plid)
64+
symbolUse, plid, plidStartCol, name)
65+
|> Array.filter(fun(_,plid,_,_)->not(List.isEmpty plid))
66+
|> Array.groupBy(fun(symbolUse,_,plidStartCol,_)-> symbolUse.RangeAlternate.StartLine, plidStartCol)
67+
|> Array.map(fun(_,xs)-> xs|> Array.maxBy(fun(symbolUse,_,_,_)-> symbolUse.RangeAlternate.EndColumn))
68+
69+
for symbolUse, plid, plidStartCol, namein symbolUsesdo
70+
ifnot symbolUse.IsFromDefinitionthen
71+
letposAtStartOfName=
72+
letr= symbolUse.RangeAlternate
73+
if r.StartLine= r.EndLinethen Range.mkPos r.StartLine(r.EndColumn- name.Length)
74+
else r.Start
75+
76+
letgetNecessaryPlid(plid:string list):Async<stringlist>=
77+
let recloop(rest:string list)(current:string list)=
78+
async{
79+
match restwith
80+
|[]->return current
81+
| headIdent:: restPlid->
82+
let!res= checkResults.IsRelativeNameResolvable(posAtStartOfName, current, symbolUse.Symbol.Item)
83+
if resthenreturn current
84+
elsereturn! loop restPlid(headIdent:: current)
85+
}
86+
loop(List.rev plid)[]
87+
88+
let!necessaryPlid= getNecessaryPlid plid|> liftAsync
89+
90+
match necessaryPlidwith
91+
| necessaryPlidwhen necessaryPlid= plid->()
92+
| necessaryPlid->
93+
letr= symbolUse.RangeAlternate
94+
letnecessaryPlidStartCol= r.EndColumn- name.Length-(getPlidLength necessaryPlid)
95+
96+
letunnecessaryRange=
97+
Range.mkRange r.FileName(Range.mkPos r.StartLine plidStartCol)(Range.mkPos r.EndLine necessaryPlidStartCol)
98+
99+
letrelativeName=(String.concat"." plid)+"."+ name
100+
result.Add(
101+
Diagnostic.Create(
102+
Descriptor,
103+
CommonRoslynHelpers.RangeToLocation(unnecessaryRange, sourceText, document.FilePath),
104+
properties=(dict[SimplifyNameDiagnosticAnalyzer.LongIdentPropertyKey, relativeName]).ToImmutableDictionary()))
105+
106+
return result.ToImmutableArray()
107+
| None->return ImmutableArray.Empty
108+
}
109+
|> Async.map(Option.defaultValue ImmutableArray.Empty)
110+
|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken
111+
112+
overridethis.AnalyzeSemanticsAsync(_,_)= Task.FromResult ImmutableArray<Diagnostic>.Empty
113+
114+
interface IBuiltInAnalyzerwith
115+
member__.OpenFileOnly _=true
116+
member__.GetAnalyzerCategory()= DiagnosticAnalyzerCategory.SemanticDocumentAnalysis

‎vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<CompileInclude="Debugging\LanguageDebugInfoService.fs" />
4848
<CompileInclude="Diagnostics\DocumentDiagnosticAnalyzer.fs" />
4949
<CompileInclude="Diagnostics\ProjectDiagnosticAnalyzer.fs" />
50+
<CompileInclude="Diagnostics\SimplifyNameDiagnosticAnalyzer.fs" />
5051
<CompileInclude="Completion\CompletionProvider.fs" />
5152
<CompileInclude="Completion\SignatureHelp.fs" />
5253
<CompileInclude="QuickInfo\QuickInfoProvider.fs" />
@@ -68,6 +69,7 @@
6869
<CompileInclude="CodeFix\ReplaceWithSuggestion.fs" />
6970
<CompileInclude="CodeFix\PrefixUnusedValueWithUnderscore.fs" />
7071
<CompileInclude="CodeFix\ImplementInterfaceCodeFixProvider.fs" />
72+
<CompileInclude="CodeFix\SimplifyName.fs" />
7173
</ItemGroup>
7274
<ItemGroup>
7375
<ProjectReferenceInclude="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">

‎vsintegration/src/FSharp.Editor/FSharp.Editor.resx‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,13 @@
132132
<dataname="RenameValueToUnderscore"xml:space="preserve">
133133
<value>Rename value to '_'</value>
134134
</data>
135+
<dataname="SimplifyName"xml:space="preserve">
136+
<value>Simplify name</value>
137+
</data>
138+
<dataname="NameCanBeSimplified"xml:space="preserve">
139+
<value>Name can be simplified.</value>
140+
</data>
141+
<dataname="StyleCategory"xml:space="preserve">
142+
<value>Style</value>
143+
</data>
135144
</root>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp