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

Commit12db301

Browse files
exclude nested symbol uses from consideration
1 parent99d0f40 commit12db301

File tree

7 files changed

+388
-235
lines changed

7 files changed

+388
-235
lines changed

‎src/fsharp/symbols/SymbolPatterns.fs‎

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,215 @@
22

33
namespaceMicrosoft.FSharp.Compiler.SourceCodeServices
44

5+
/// Patterns over FSharpSymbol and derivatives.
6+
[<RequireQualifiedAccess>]
7+
moduleSymbol=
8+
openSystem.Text.RegularExpressions
9+
openSystem
10+
11+
letisAttribute<'T>(attribute:FSharpAttribute)=
12+
// CompiledName throws exception on DataContractAttribute generated by SQLProvider
13+
try attribute.AttributeType.CompiledName= typeof<'T>.Namewith_->false
14+
15+
lettryGetAttribute<'T>(attributes:seq<FSharpAttribute>)=
16+
attributes|> Seq.tryFind isAttribute<'T>
17+
18+
moduleOption=
19+
letattempt f=try Some(f())with_-> None
20+
21+
lethasModuleSuffixAttribute(entity:FSharpEntity)=
22+
entity.Attributes
23+
|> tryGetAttribute<CompilationRepresentationAttribute>
24+
|> Option.bind(fun a->
25+
Option.attempt(fun _-> a.ConstructorArguments)
26+
|> Option.bind(fun args-> args|> Seq.tryPick(fun(_,arg)->
27+
letres=
28+
match argwith
29+
|:? int32as argwhen arg= int CompilationRepresentationFlags.ModuleSuffix->
30+
Some()
31+
|:? CompilationRepresentationFlagsas argwhen arg= CompilationRepresentationFlags.ModuleSuffix->
32+
Some()
33+
|_->
34+
None
35+
res)))
36+
|> Option.isSome
37+
38+
letisOperator(name:string)=
39+
name.StartsWith"("&& name.EndsWith" )"&& name.Length>4
40+
&& name.Substring(2, name.Length-4)
41+
|> String.forall(fun c-> c<>' '&&not(Char.IsLetter c))
42+
43+
letUnnamedUnionFieldRegex= Regex("^Item(\d+)?$", RegexOptions.Compiled)
44+
45+
letisUnnamedUnionCaseField(field:FSharpField)= UnnamedUnionFieldRegex.IsMatch(field.Name)
46+
47+
let(|AbbreviatedType|_|)(entity:FSharpEntity)=
48+
if entity.IsFSharpAbbreviationthen Some entity.AbbreviatedType
49+
else None
50+
51+
let(|TypeWithDefinition|_|)(ty:FSharpType)=
52+
if ty.HasTypeDefinitionthen Some ty.TypeDefinition
53+
else None
54+
55+
let recgetEntityAbbreviatedType(entity:FSharpEntity)=
56+
if entity.IsFSharpAbbreviationthen
57+
match entity.AbbreviatedTypewith
58+
| TypeWithDefinition def-> getEntityAbbreviatedType def
59+
| abbreviatedType-> entity, Some abbreviatedType
60+
else entity, None
61+
62+
let recgetAbbreviatedType(fsharpType:FSharpType)=
63+
if fsharpType.IsAbbreviationthen
64+
getAbbreviatedType fsharpType.AbbreviatedType
65+
else fsharpType
66+
67+
let(|Attribute|_|)(entity:FSharpEntity)=
68+
letisAttribute(entity:FSharpEntity)=
69+
letgetBaseType(entity:FSharpEntity)=
70+
try
71+
match entity.BaseTypewith
72+
| Some(TypeWithDefinition def)-> Some def
73+
|_-> None
74+
with_-> None
75+
76+
let recisAttributeType(ty:FSharpEntity option)=
77+
match tywith
78+
| None->false
79+
| Some ty->
80+
try ty.FullName="System.Attribute"|| isAttributeType(getBaseType ty)
81+
with_->false
82+
isAttributeType(Some entity)
83+
if isAttribute entitythen Some()else None
84+
85+
lethasAttribute<'T>(attributes:seq<FSharpAttribute>)=
86+
attributes|> Seq.exists isAttribute<'T>
87+
88+
let(|ValueType|_|)(e:FSharpEntity)=
89+
if e.IsEnum|| e.IsValueType|| hasAttribute<MeasureAnnotatedAbbreviationAttribute> e.Attributesthen Some()
90+
else None
91+
92+
let(|Class|_|)(original:FSharpEntity,abbreviated:FSharpEntity,_)=
93+
if abbreviated.IsClass
94+
&&(not abbreviated.IsStaticInstantiation|| original.IsFSharpAbbreviation)then Some()
95+
else None
96+
97+
let(|Record|_|)(e:FSharpEntity)=if e.IsFSharpRecordthen Some()else None
98+
let(|UnionType|_|)(e:FSharpEntity)=if e.IsFSharpUnionthen Some()else None
99+
let(|Delegate|_|)(e:FSharpEntity)=if e.IsDelegatethen Some()else None
100+
let(|FSharpException|_|)(e:FSharpEntity)=if e.IsFSharpExceptionDeclarationthen Some()else None
101+
let(|Interface|_|)(e:FSharpEntity)=if e.IsInterfacethen Some()else None
102+
let(|AbstractClass|_|)(e:FSharpEntity)=
103+
if hasAttribute<AbstractClassAttribute> e.Attributesthen Some()else None
104+
105+
let(|FSharpType|_|)(e:FSharpEntity)=
106+
if e.IsDelegate|| e.IsFSharpExceptionDeclaration|| e.IsFSharpRecord|| e.IsFSharpUnion
107+
|| e.IsInterface|| e.IsMeasure
108+
||(e.IsFSharp&& e.IsOpaque&&not e.IsFSharpModule&&not e.IsNamespace)then Some()
109+
else None
110+
111+
let(|ProvidedType|_|)(e:FSharpEntity)=
112+
if(e.IsProvided|| e.IsProvidedAndErased|| e.IsProvidedAndGenerated)&& e.CompiledName= e.DisplayNamethen
113+
Some()
114+
else None
115+
116+
let(|ByRef|_|)(e:FSharpEntity)=if e.IsByRefthen Some()else None
117+
let(|Array|_|)(e:FSharpEntity)=if e.IsArrayTypethen Some()else None
118+
let(|FSharpModule|_|)(entity:FSharpEntity)=if entity.IsFSharpModulethen Some()else None
119+
120+
let(|Namespace|_|)(entity:FSharpEntity)=if entity.IsNamespacethen Some()else None
121+
let(|ProvidedAndErasedType|_|)(entity:FSharpEntity)=if entity.IsProvidedAndErasedthen Some()else None
122+
let(|Enum|_|)(entity:FSharpEntity)=if entity.IsEnumthen Some()else None
123+
124+
let(|Tuple|_|)(ty:FSharpType option)=
125+
ty|> Option.bind(fun ty->if ty.IsTupleTypethen Some()else None)
126+
127+
let(|RefCell|_|)(ty:FSharpType)=
128+
match getAbbreviatedType tywith
129+
| TypeWithDefinition defwhen
130+
def.IsFSharpRecord&& def.FullName="Microsoft.FSharp.Core.FSharpRef`1"-> Some()
131+
|_-> None
132+
133+
let(|FunctionType|_|)(ty:FSharpType)=
134+
if ty.IsFunctionTypethen Some()
135+
else None
136+
137+
let(|Pattern|_|)(symbol:FSharpSymbol)=
138+
match symbolwith
139+
|:? FSharpUnionCase
140+
|:? FSharpActivePatternCase-> Some()
141+
|_-> None
142+
143+
/// Field (field, fieldAbbreviatedType)
144+
let(|Field|_|)(symbol:FSharpSymbol)=
145+
match symbolwith
146+
|:? FSharpFieldas field-> Some(field, getAbbreviatedType field.FieldType)
147+
|_-> None
148+
149+
let(|MutableVar|_|)(symbol:FSharpSymbol)=
150+
letisMutable=
151+
match symbolwith
152+
|:? FSharpFieldas field-> field.IsMutable&&not field.IsLiteral
153+
|:? FSharpMemberOrFunctionOrValueas func-> func.IsMutable
154+
|_->false
155+
if isMutablethen Some()else None
156+
157+
/// Entity (originalEntity, abbreviatedEntity, abbreviatedType)
158+
let(|FSharpEntity|_|)(symbol:FSharpSymbol)=
159+
match symbolwith
160+
|:? FSharpEntityas entity->
161+
letabbreviatedEntity,abbreviatedType= getEntityAbbreviatedType entity
162+
Some(entity, abbreviatedEntity, abbreviatedType)
163+
|_-> None
164+
165+
let(|Parameter|_|)(symbol:FSharpSymbol)=
166+
match symbolwith
167+
|:? FSharpParameter-> Some()
168+
|_-> None
169+
170+
let(|UnionCase|_|)(e:FSharpSymbol)=
171+
match ewith
172+
|:? FSharpUnionCaseas uc-> Some uc
173+
|_-> None
174+
175+
let(|RecordField|_|)(e:FSharpSymbol)=
176+
match ewith
177+
|:? FSharpFieldas field->
178+
if field.DeclaringEntity.IsFSharpRecordthen Some fieldelse None
179+
|_-> None
180+
181+
let(|ActivePatternCase|_|)(symbol:FSharpSymbol)=
182+
match symbolwith
183+
|:? FSharpActivePatternCaseas case-> Some case
184+
|_-> None
185+
186+
/// Func (memberFunctionOrValue, fullType)
187+
let(|MemberFunctionOrValue|_|)(symbol:FSharpSymbol)=
188+
match symbolwith
189+
|:? FSharpMemberOrFunctionOrValueas func-> Some func
190+
|_-> None
191+
192+
/// Constructor (enclosingEntity)
193+
let(|Constructor|_|)(func:FSharpMemberOrFunctionOrValue)=
194+
match func.CompiledNamewith
195+
|".ctor"|".cctor"-> func.EnclosingEntity
196+
|_-> None
197+
198+
let(|Function|_|)excluded(func:FSharpMemberOrFunctionOrValue)=
199+
trylettyp= func.FullType|> getAbbreviatedType
200+
if typ.IsFunctionType
201+
&&not func.IsPropertyGetterMethod
202+
&&not func.IsPropertySetterMethod
203+
&&not excluded
204+
&&not(isOperator func.DisplayName)then Some()
205+
else None
206+
with_-> None
207+
208+
let(|ExtensionMember|_|)(func:FSharpMemberOrFunctionOrValue)=
209+
if func.IsExtensionMemberthen Some()else None
210+
211+
let(|Event|_|)(func:FSharpMemberOrFunctionOrValue)=
212+
if func.IsEventthen Some()else None
213+
5214
/// Active patterns over `FSharpSymbolUse`.
6215
[<RequireQualifiedAccess>]
7216
moduleSymbolUse=

‎src/fsharp/symbols/SymbolPatterns.fsi‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,59 @@
22

33
namespaceMicrosoft.FSharp.Compiler.SourceCodeServices
44

5+
[<RequireQualifiedAccess>]
6+
#if COMPILER_PUBLIC_API
7+
moduleSymbol=
8+
#else
9+
moduleinternalSymbol=
10+
#endif
11+
openSystem.Text.RegularExpressions
12+
openSystem
13+
14+
valisAttribute<'T>:FSharpAttribute->bool
15+
valtryGetAttribute<'T>:seq<FSharpAttribute>->FSharpAttribute option
16+
valhasModuleSuffixAttribute:FSharpEntity->bool
17+
valisOperator:name:string->bool
18+
valisUnnamedUnionCaseField:FSharpField->bool
19+
val(|AbbreviatedType|_|):FSharpEntity->FSharpType option
20+
val(|TypeWithDefinition|_|):FSharpType->FSharpEntity option
21+
valgetEntityAbbreviatedType:FSharpEntity->(FSharpEntity* FSharpType option)
22+
valgetAbbreviatedType:FSharpType->FSharpType
23+
val(|Attribute|_|):FSharpEntity->unit option
24+
valhasAttribute<'T>:seq<FSharpAttribute>->bool
25+
val(|ValueType|_|):FSharpEntity->unit option
26+
val(|Class|_|):original:FSharpEntity* abbreviated: FSharpEntity* 'a-> unit option
27+
val(|Record|_|): FSharpEntity-> unit option
28+
val(|UnionType|_|): FSharpEntity-> unit option
29+
val(|Delegate|_|): FSharpEntity-> unit option
30+
val(|FSharpException|_|): FSharpEntity-> unit option
31+
val(|Interface|_|): FSharpEntity-> unit option
32+
val(|AbstractClass|_|): FSharpEntity-> unit option
33+
val(|FSharpType|_|): FSharpEntity-> unit option
34+
val(|ProvidedType|_|): FSharpEntity-> unit option
35+
val(|ByRef|_|): FSharpEntity-> unit option
36+
val(|Array|_|): FSharpEntity-> unit option
37+
val(|FSharpModule|_|): FSharpEntity-> unit option
38+
val(|Namespace|_|): FSharpEntity-> unit option
39+
val(|ProvidedAndErasedType|_|): FSharpEntity-> unit option
40+
val(|Enum|_|): FSharpEntity-> unit option
41+
val(|Tuple|_|): FSharpType option-> unit option
42+
val(|RefCell|_|): FSharpType-> unit option
43+
val(|FunctionType|_|): FSharpType-> unit option
44+
val(|Pattern|_|): FSharpSymbol-> unit option
45+
val(|Field|_|): FSharpSymbol->(FSharpField* FSharpType) option
46+
val(|MutableVar|_|): FSharpSymbol-> unit option
47+
val(|FSharpEntity|_|): FSharpSymbol->(FSharpEntity* FSharpEntity* FSharpType option) option
48+
val(|Parameter|_|): FSharpSymbol-> unit option
49+
val(|UnionCase|_|): FSharpSymbol-> FSharpUnionCase option
50+
val(|RecordField|_|): FSharpSymbol-> FSharpField option
51+
val(|ActivePatternCase|_|): FSharpSymbol-> FSharpActivePatternCase option
52+
val(|MemberFunctionOrValue|_|): FSharpSymbol-> FSharpMemberOrFunctionOrValue option
53+
val(|Constructor|_|): FSharpMemberOrFunctionOrValue-> FSharpEntity option
54+
val(|Function|_|): excluded: bool-> FSharpMemberOrFunctionOrValue-> unit option
55+
val(|ExtensionMember|_|): FSharpMemberOrFunctionOrValue-> unit option
56+
val(|Event|_|): FSharpMemberOrFunctionOrValue-> unit option
57+
558
[<RequireQualifiedAccess>]
659
#if COMPILER_PUBLIC_API
760
module SymbolUse=

‎src/fsharp/vs/ServiceAnalysis.fs‎

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ module UnusedOpens =
114114
|> List.concat
115115
|> List.choose id
116116

117+
typeSymbolUseWithFullNames=
118+
{ SymbolUse:FSharpSymbolUse
119+
FullNames:string[][]}
120+
117121
letgetNamespacesInUse(getSourceLineStr:int->string)(symbolUses:FSharpSymbolUse[]):NamespaceUse list=
118122
letimportantSymbolUses=
119123
symbolUses
@@ -124,8 +128,106 @@ module UnusedOpens =
124128
|_->true
125129
)
126130

127-
importantSymbolUses
128-
|> Array.toList
131+
letsymbolUsesWithFullNames:SymbolUseWithFullNames[]=
132+
importantSymbolUses
133+
|> Array.map(fun symbolUse->
134+
letfullNames:string[][]=
135+
match symbolUse.Symbolwith
136+
| Symbol.MemberFunctionOrValue funcwhen func.IsExtensionMember->
137+
if func.IsPropertythen
138+
letfullNames=
139+
[|
140+
if func.HasGetterMethodthen
141+
yieldtry func.GetterMethod.EnclosingEntity|> Option.map(fun x-> x.FullName)with_-> None
142+
if func.HasSetterMethodthen
143+
yieldtry func.SetterMethod.EnclosingEntity|> Option.map(fun x-> x.FullName)with_-> None
144+
|]
145+
|> Array.choose id
146+
match fullNameswith
147+
|[||]-> None
148+
|_-> Some fullNames
149+
else
150+
match func.EnclosingEntitywith
151+
// C# extension method
152+
| Some(Symbol.FSharpEntity Symbol.Class)->
153+
letfullName= symbolUse.Symbol.FullName.Split'.'
154+
if fullName.Length>2then
155+
(* For C# extension methods FCS returns full name including the class name, like:
156+
Namespace.StaticClass.ExtensionMethod
157+
So, in order to properly detect that "open Namespace" actually opens ExtensionMethod,
158+
we remove "StaticClass" part. This makes C# extension methods looks identically
159+
with F# extension members.
160+
*)
161+
letfullNameWithoutClassName=
162+
Array.append fullName.[0..fullName.Length-3] fullName.[fullName.Length-1..]
163+
Some[|fullNameWithoutClassName|> String.concat"."|]
164+
else None
165+
|_-> None
166+
// Operators
167+
| Symbol.MemberFunctionOrValue func->
168+
match funcwith
169+
| Symbol.Constructor_->
170+
// full name of a constructor looks like "UnusedSymbolClassifierTests.PrivateClass.( .ctor )"
171+
// to make well formed full name parts we cut "( .ctor )" from the tail.
172+
letfullName= func.FullName
173+
letctorSuffix=".( .ctor )"
174+
letfullName=
175+
if fullName.EndsWith ctorSuffixthen
176+
fullName.[0..fullName.Length- ctorSuffix.Length-1]
177+
else fullName
178+
Some[| fullName|]
179+
|_->
180+
Some[|yield func.FullName
181+
match func.TryGetFullCompiledOperatorNameIdents()with
182+
| Some idents->yield String.concat"." idents
183+
| None->()
184+
|]
185+
| Symbol.FSharpEntity e->
186+
match ewith
187+
| e, Symbol.Attribute,_->
188+
e.TryGetFullName()
189+
|> Option.map(fun fullName->
190+
[| fullName; fullName.Substring(0, fullName.Length-"Attribute".Length)|])
191+
| e,_,_->
192+
e.TryGetFullName()|> Option.map(fun fullName->[| fullName|])
193+
//| SymbolUse.RecordField _
194+
| Symbol.UnionCase_as symbol->
195+
Some[|letfullName= symbol.FullName
196+
yield fullName
197+
letidents= fullName.Split'.'
198+
// Union cases/Record fields can be accessible without mentioning the enclosing type.
199+
// So we add a FullName without having the type part.
200+
if idents.Length>1then
201+
yield Array.append idents.[0..idents.Length-3] idents.[idents.Length-1..]|> String.concat"."
202+
|]
203+
|_-> None
204+
|> Option.defaultValue[|symbolUse.Symbol.FullName|]
205+
|> Array.map(fun fullName-> fullName.Split'.')
206+
207+
{ SymbolUse= symbolUse
208+
FullNames= fullNames})
209+
210+
letouterSymbolUses=
211+
symbolUsesWithFullNames
212+
|> Seq.sortBy(fun x->-x.SymbolUse.RangeAlternate.EndColumn)
213+
|> Seq.fold(fun(prev,acc)next->
214+
match prevwith
215+
| Some prev->
216+
if prev.FullNames
217+
|> Array.exists(fun prevFullName->
218+
next.FullNames
219+
|> Array.exists(fun nextFullName->
220+
nextFullName.Length< prevFullName.Length
221+
&& prevFullName|> Microsoft.FSharp.Compiler.AbstractIL.Internal.Library.Array.startsWith nextFullName))then
222+
Some prev, acc
223+
else Some next, next:: acc
224+
| None-> Some next, next:: acc)
225+
(None,[])
226+
|> snd
227+
|> List.map(fun x-> x.SymbolUse)
228+
|> List.rev
229+
230+
outerSymbolUses
129231
|> List.collect(fun su->
130232
letlineStr= getSourceLineStr su.RangeAlternate.StartLine
131233
letpartialName= QuickParse.GetPartialLongNameEx(lineStr, su.RangeAlternate.EndColumn-1)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp