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

Commit0982b92

Browse files
make the rest of nr lazy
add cache
1 parent990b01e commit0982b92

File tree

2 files changed

+94
-58
lines changed

2 files changed

+94
-58
lines changed

‎src/fsharp/NameResolution.fs‎

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3905,6 +3905,7 @@ let GetVisibleNamespacesAndModulesAtPoint (ncenv: NameResolver) (nenv: NameResol
39053905
&& EntityRefContainsSomethingAccessible ncenv m ad x
39063906
&&not(IsTyconUnseen ad ncenv.g ncenv.amap m x))
39073907

3908+
(* Determining if an `Item` is resolvable at point by given `plid`. It's optimized by being lazy and early returning according to the given `Item`*)
39083909

39093910
letprivateResolveCompletionsInTypeForItem(ncenv:NameResolver)nenv m ad statics typ(item:Item):seq<Item>=
39103911
seq{
@@ -4205,6 +4206,28 @@ let rec private ResolvePartialLongIdentInModuleOrNamespaceForItem (ncenv: NameRe
42054206
yield! tcref|> generalizedTyconRef|> ResolvePartialLongIdentInTypeForItem ncenv nenv m adtrue rest item
42064207
}
42074208

4209+
let recprivatePartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f plid(modref:ModuleOrNamespaceRef)=
4210+
letmty= modref.ModuleOrNamespaceType
4211+
match plidwith
4212+
|[]-> f modref
4213+
| id:: rest->
4214+
match mty.ModulesAndNamespacesByDemangledName.TryFind idwith
4215+
| Some mty->
4216+
PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f rest(modref.NestedTyconRef mty)
4217+
| None-> Seq.empty
4218+
4219+
letprivatePartialResolveLongIndentAsModuleOrNamespaceThenLazy(nenv:NameResolutionEnv)plid f=
4220+
seq{
4221+
match plidwith
4222+
| id:: rest->
4223+
match Map.tryFind id nenv.eModulesAndNamespaceswith
4224+
| Some modrefs->
4225+
for modrefin modrefsdo
4226+
yield! PartialResolveLookupInModuleOrNamespaceAsModuleOrNamespaceThenLazy f rest modref
4227+
| None->()
4228+
|[]->()
4229+
}
4230+
42084231
let recprivateGetCompletionForItem(ncenv:NameResolver)(nenv:NameResolutionEnv)m ad plid(item:Item):seq<Item>=
42094232
seq{
42104233
letg= ncenv.g
@@ -4258,10 +4281,10 @@ let rec private GetCompletionForItem (ncenv: NameResolver) (nenv: NameResolution
42584281

42594282
// Look in the namespaces 'id'
42604283
yield!
4261-
PartialResolveLongIndentAsModuleOrNamespaceThen nenv[id](fun modref->
4284+
PartialResolveLongIndentAsModuleOrNamespaceThenLazy nenv[id](fun modref->
42624285
if EntityRefContainsSomethingAccessible ncenv m ad modrefthen
4263-
ResolvePartialLongIdentInModuleOrNamespaceForItem ncenv nenv m ad modref rest item|> Seq.toList
4264-
else[])
4286+
ResolvePartialLongIdentInModuleOrNamespaceForItem ncenv nenv m ad modref rest item
4287+
elseSeq.empty)
42654288

42664289
// Look for values called 'id' that accept the dot-notation
42674290
letvalues,isItemVal=

‎vsintegration/src/FSharp.Editor/Diagnostics/SimplifyNameDiagnosticAnalyzer.fs‎

Lines changed: 68 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ open Microsoft.FSharp.Compiler.SourceCodeServices
1717

1818
openMicrosoft.VisualStudio.FSharp.LanguageService
1919

20-
typeprivateLineHash= int
20+
typeprivateTextVersionHash= int
2121

2222
[<DiagnosticAnalyzer(FSharpCommonConstants.FSharpLanguageName)>]
2323
typeinternalSimplifyNameDiagnosticAnalyzer()=
@@ -26,6 +26,7 @@ type internal SimplifyNameDiagnosticAnalyzer() =
2626
letgetProjectInfoManager(document:Document)= document.Project.Solution.Workspace.Services.GetService<FSharpCheckerWorkspaceService>().ProjectInfoManager
2727
letgetChecker(document:Document)= document.Project.Solution.Workspace.Services.GetService<FSharpCheckerWorkspaceService>().Checker
2828
letgetPlidLength(plid:string list)=(plid|> List.sumBy String.length)+ plid.Length
29+
static letcache= ConditionalWeakTable<DocumentId, TextVersionHash* ImmutableArray<Diagnostic>>()
2930

3031
static letDescriptor=
3132
DiagnosticDescriptor(
@@ -47,63 +48,75 @@ type internal SimplifyNameDiagnosticAnalyzer() =
4748
asyncMaybe{
4849
match getProjectInfoManager(document).TryGetOptionsForEditingDocumentOrProject(document)with
4950
| 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))
51+
let!textVersion= document.GetTextVersionAsync(cancellationToken)
52+
lettextVersionHash= textVersion.GetHashCode()
6853

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
54+
return! lock cache(fun _->
55+
asyncMaybe{
56+
match cache.TryGetValue document.Idwith
57+
|true,(oldTextVersionHash, diagnostics)when oldTextVersionHash= textVersionHash->return diagnostics
58+
|_->
59+
let!sourceText= document.GetTextAsync()
60+
letchecker= getChecker document
61+
let!_,checkResults= checker.ParseAndCheckDocument(document, options, sourceText)
62+
let!symbolUses= checkResults.GetAllUsesOfAllSymbolsInFile()|> liftAsync
63+
let mutableresult= ResizeArray()
64+
letsymbolUses=
65+
symbolUses
66+
|> Array.Parallel.map(fun symbolUse->
67+
letlineStr= sourceText.Lines.[Line.toZ symbolUse.RangeAlternate.StartLine].ToString()
68+
// for `System.DateTime.Now` it returns ([|"System"; "DateTime"|], "Now")
69+
letplid,name= QuickParse.GetPartialLongNameEx(lineStr, symbolUse.RangeAlternate.EndColumn-1)
70+
// `symbolUse.RangeAlternate.Start` does not point to the start of plid, it points to start of `name`,
71+
// so we have to calculate plid's start ourselves.
72+
letplidStartCol= symbolUse.RangeAlternate.EndColumn- name.Length-(getPlidLength plid)
73+
symbolUse, plid, plidStartCol, name)
74+
|> Array.filter(fun(_,plid,_,_)->not(List.isEmpty plid))
75+
|> Array.groupBy(fun(symbolUse,_,plidStartCol,_)-> symbolUse.RangeAlternate.StartLine, plidStartCol)
76+
|> Array.map(fun(_,xs)-> xs|> Array.maxBy(fun(symbolUse,_,_,_)-> symbolUse.RangeAlternate.EndColumn))
8977

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)
78+
for symbolUse, plid, plidStartCol, namein symbolUsesdo
79+
ifnot symbolUse.IsFromDefinitionthen
80+
letposAtStartOfName=
81+
letr= symbolUse.RangeAlternate
82+
if r.StartLine= r.EndLinethen Range.mkPos r.StartLine(r.EndColumn- name.Length)
83+
else r.Start
9884

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()
85+
letgetNecessaryPlid(plid:string list):Async<stringlist>=
86+
let recloop(rest:string list)(current:string list)=
87+
async{
88+
match restwith
89+
|[]->return current
90+
| headIdent:: restPlid->
91+
let!res= checkResults.IsRelativeNameResolvable(posAtStartOfName, current, symbolUse.Symbol.Item)
92+
if resthenreturn current
93+
elsereturn! loop restPlid(headIdent:: current)
94+
}
95+
loop(List.rev plid)[]
96+
97+
let!necessaryPlid= getNecessaryPlid plid|> liftAsync
98+
99+
match necessaryPlidwith
100+
| necessaryPlidwhen necessaryPlid= plid->()
101+
| necessaryPlid->
102+
letr= symbolUse.RangeAlternate
103+
letnecessaryPlidStartCol= r.EndColumn- name.Length-(getPlidLength necessaryPlid)
104+
105+
letunnecessaryRange=
106+
Range.mkRange r.FileName(Range.mkPos r.StartLine plidStartCol)(Range.mkPos r.EndLine necessaryPlidStartCol)
107+
108+
letrelativeName=(String.concat"." plid)+"."+ name
109+
result.Add(
110+
Diagnostic.Create(
111+
Descriptor,
112+
CommonRoslynHelpers.RangeToLocation(unnecessaryRange, sourceText, document.FilePath),
113+
properties=(dict[SimplifyNameDiagnosticAnalyzer.LongIdentPropertyKey, relativeName]).ToImmutableDictionary()))
114+
115+
letdiagnostics= result.ToImmutableArray()
116+
cache.Remove(document.Id)|> ignore
117+
cache.Add(document.Id,(textVersionHash, diagnostics))
118+
return diagnostics
119+
})
107120
| None->return ImmutableArray.Empty
108121
}
109122
|> Async.map(Option.defaultValue ImmutableArray.Empty)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp