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

Commiteb72891

Browse files
dsymepsfinaki
andauthored
Fixing a few edge cases around display name (+cleanup) (#13552)
* cleanup some things around names* more rigorously separate display names, core display names and logical names* fix build* Fixing build* Update* Fixed a test* Fixed a test* Fixing more tests* Update PrettyNaming.fs* Update* Update* ok* conflict* Added a test* Added another test* And another test* Minor stuffCo-authored-by: Peter Semkin <petersemkin@duck.com>Co-authored-by: Petr <psfinaki@users.noreply.github.com>
1 parent2f3a78a commiteb72891

File tree

45 files changed

+996
-451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+996
-451
lines changed

‎.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,5 @@ nCrunchTemp_*
123123

124124
/test.fs
125125
/test.fsx
126+
127+
tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.actual

‎docs/names.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
---
2+
title:Display names, logical names and compiled names
3+
category:Compiler Internals
4+
categoryindex:200
5+
index:350
6+
---
7+
#Names of entities and values in the F# Compiler
8+
9+
The F# tooling distinguishes between the following concepts of "name" for values, union cases, class/record fields and entities:
10+
11+
* Display names as they appear in code
12+
13+
Characteristics:
14+
- For most identifiers, have double backticks, e.g.` ``Module name with spaces```
15+
- For operator names, are short and parenthesized, e.g.`(+)` for the logical name`op_Addition`
16+
- For active patterns, are parenthesized, e.g.`(|A|_|)`
17+
- etc., see exact specification below
18+
19+
Used in:
20+
- Code outputs, e.g. signature files
21+
- Diagnostics (BUG: not consistently the case today)
22+
23+
Current aliases in code:
24+
-`vref.DisplayName`
25+
-`entity.DisplayName`
26+
-`entity.DisplayNameWithStaticParameters`
27+
-`entity.DisplayNameWithStaticParametersAndUnderscoreTypars`
28+
-`minfo.DisplayName`
29+
-`pinfo.DisplayName`
30+
-`einfo.DisplayName`
31+
- etc.
32+
33+
* Display names as they appear in declaration lists, navigation etc.
34+
35+
Characteristics:
36+
- Same as above without the double backticks or parentheses
37+
38+
Current aliases in code:
39+
-`vref.DisplayNameCore`
40+
-`entity.DisplayNameCore`
41+
-`minfo.DisplayNameCore`
42+
-`pinfo.DisplayNameCore`
43+
-`einfo.DisplayNameCore`
44+
- etc.
45+
46+
* Logical names
47+
48+
Characteristics:
49+
- Are used in`TypedTree`, often "canonical"
50+
- Sometimes require extra flags to qualify the meaning of the name
51+
52+
Current aliases in code:
53+
-`vref.LogicalName`
54+
-`entity.LogicalName`
55+
-`minfo.LogicalName`
56+
-`pinfo.PropertyName`
57+
-`einfo.EventName`
58+
- etc.
59+
60+
* Compiled names
61+
62+
Characterists:
63+
- Mark the names that appear in the .NET IL
64+
65+
Current aliases in code:
66+
-`vref.CompiledName`
67+
-`entity.CompiledName`
68+
- etc.
69+
70+
71+
##Specification of all logical names
72+
73+
The following tables loosely characterise the variations in logical names, how
74+
they correspond to F# source constructs and the`SyntaxTree`/`TypedTree` metadata for these.
75+
76+
Entities:
77+
78+
Display name in code | Logical name | Notes
79+
----------------------------|----------------|-------
80+
C | C | type definition
81+
C | C`1 | e.g. generic type, see notes below for variations of display names
82+
M | M | module definition
83+
M | MModule | "ModuleSuffix" attribute for F# modules, now somewhat legacy, rarely used, but still allowed; also where "ModuleSuffix" is implied because type and module have the same name
84+
JsonProvider<"foo.json"> | JsonProvider,Schema=\"xyz\" | static parameters, see notes below for variations of display names
85+
86+
Values:
87+
88+
Display name in code | Relation | Logical name | Notes
89+
---------------------|----------|----------------------|------
90+
(+) | <--> | op_Addition |
91+
(+ ) | --> | op_Addition | not reversed
92+
op_Addition | --> | op_Addition | not reversed
93+
(*) | <--> | op_Multiply |
94+
( * ) | --> | op_Multiply | not reversed
95+
op_Multiply | --> | op_Multiply | not reversed
96+
(*+ ) | <--> | op_MultiplyPlus |
97+
(*+ ) | --> | op_MultiplyPlus | not reversed
98+
op_MultiplyPlus | --> | op_MultiplyPlus | not reversed
99+
(+++) | <--> | op_PlusPlusPlus |
100+
op_PlusPlusPlus | --> | op_PlusPlusPlus | not reversed
101+
(%) | <--> | op_Modulus |
102+
op_Modulus | --> | op_Modulus |
103+
(?) | <--> | op_Dynamic | not defined by default, for x?SomeThing
104+
(?<-) | <--> | op_DynamicAssignment | not defined by default, for x?SomeThing <- "a"
105+
(..) | <--> | op_Range | for "3 .. 5"
106+
(.. ..) | <--> | op_RangeStep | for "5 .. -1 .. 3"
107+
or | <--> | or |
108+
mod | <--> | mod |
109+
``let`` | <--> | let | this is a keyword, in code it appears as``let``
110+
``type`` | <--> | type | this is a keyword, in code it appears as``type``
111+
base | <--> | base | for IsBaseVal=true only. Base is a keyword, this is a special base val
112+
``base`` | <--> | base | for IsBaseVal=false only. Base is a keyword, this is not a special base val
113+
SomeClass | <--> | .ctor | IsConstructor=true
114+
``.ctor`` | <--> | .ctor | IsConstructor=false, this is only allowed for let-definitions, e.g. let``.ctor`` x = 1
115+
<not-shown> | <--> | .cctor | IsClassConstructor=true, should never really appear in diagnostics or user-facing output
116+
``.cctor`` | <--> | .cctor | IsClassConstructor=false, this is only allowed for let-definitions, e.g. let``.cctor`` x = 1
117+
(\|A\|_\|) | <--> |\|A\|_\| |
118+
(\|A\|_\|) | --> |\|A\|_\| | not reversed
119+
P | <--> | get_P | IsPropertyGetterMethod = true
120+
P | <--> | set_P | IsPropertySetterMethod = true
121+
122+
Other Val constructs less problematic for naming are:
123+
124+
Display name in code | Relation | Logical name | Notes
125+
---------------------|----------|----------------------|------
126+
this | <--> | this | IsCtorThisVal = true; From`type C() as this`; Can have any name, not particularly special with regard to names; This has a 'ref' type for initialization checks
127+
this | <--> | this | IsMemberThisVal = true; From`member this.M() = ...`; This can have a 'ref' type for initialization checks; Can have any name, not particularly special with regard to names
128+
\<not-shown\> | <--> | System.IDisposable.Dispose | ImplementedSlotSigs is non-empty, i.e. length 1, should never really appear in diagnostics or user-facing output
129+
130+
Union cases:
131+
132+
Display name in code | Relation | Logical name | Notes
133+
---------------------|----------|----------------------|------
134+
SomeCase | <--> | SomeCase
135+
` ``Case with space``` | <--> | Case with space
136+
` ``type``` | <--> | type | This is a keyword
137+
(::) | <--> | op_ColonColon | This is the logical name for the cons union case on`FSharpList` only
138+
[] | <--> | op_Nil | This is the logical name for the nil case on`FSharpList` only
139+
140+
Class and record fields, enum cases, active pattern cases, anonymous record fields:
141+
142+
Display name in code | Relation | Logical name | Notes
143+
---------------------|----------|----------------------|------
144+
SomeField | <--> | SomeField
145+
` ``Field with space```| <--> | Field with space
146+
` ``type``` | <--> | type | This is a keyword
147+
148+
Generic parameters:
149+
150+
Display name in code | Relation | Logical name | Notes
151+
---------------------|----------|----------------------|------
152+
'T | <--> | T
153+
'` ``T T T``` | <--> | T T T | BUG: the backticks are not currently added
154+
'` ``type``` | <--> | type | This is a keyword, BUG: the backticks are not currently added
155+
156+
##Variations on display names
157+
158+
In different display settings, Entities/Types/Modules can have some variations on display names. For example, when showing some kinds of output we may set`shortTypeNames=true` which will never show full names.
159+
160+
*`SomeTypeProvider`
161+
- Used for omitting static parameters
162+
- Alias in code:`entity.CompiledName`
163+
164+
*`SomeTypeProvider<...>`
165+
- Used for eliding static parameters
166+
167+
*`SomeTypeProvider<"foo.json">`
168+
- Used for showing static parameters. These can be very large, e.g. entire connection strings, so better to elide or omit.
169+
- Alias in code:`entity.DisplayNameWithStaticParameters`
170+
171+
*`List<_>`
172+
- Used with underscore typars
173+
- Alias in code:`entity.DisplayNameWithStaticParametersAndUnderscoreTypars`
174+
175+
*`Dictionary<'TKey,'TResult>`
176+
- Used with general typars
177+
178+
* Full name
179+
180+
Examples:
181+
-`SomeNamespace.OtherNamespace.SomeType`
182+
-``` ``Some Namespace With Spaces``.SomeType``` <-- BUG: not double-ticks today
183+
-`SomeEnclosingType<_>.SomeStaticMethod` <-- BUG: the mangled generic type counts are shown today
184+
185+
186+
##Compiled names
187+
188+
The name that appears in the .NET IL.
189+
190+
Affected by:
191+
-`CompiledName` attribute
192+
- some heuristics for generic type parameters
193+
194+
Also the name from signature is generally preferred; if there is any difference, a warning is emitted.
195+
196+
Example of how signature affects compiled names
197+
198+
```fsharp
199+
Foo.fsi
200+
201+
val SomeFunction: x: int -> y: int -> int
202+
203+
Foo.fs
204+
205+
let SomeFunction a b = a + b // compiled name of parameters is x, y - warning emitted
206+
```

‎release-notes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ These release notes track our current efforts to document changes to the F# proj
3535
*`SynMeasure` was extended with[SynMeasure.Paren](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synmeasure.html#Paren) case.
3636
* Dynamic expressions (like`x?y`) are now represented as[SynExpr.Dynamic](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synexpr.html#Dynamic) in the Untyped Syntax Tree.
3737
* Members with`get` and/or`set` are now represented as[SynMemberDefn.GetSetMember](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synmemberdefn.html#GetSetMember) in the Untyped Syntax Tree.
38+
*`DoesIdentifierNeedBackticks` is removed, it should always be sufficient to call`NormalizeIdentifierBackticks` or else call something in`PrettyNaming`
39+
*`AddBackticksToIdentifierIfNeeded` is removed, it should always be sufficient to call`NormalizeIdentifierBackticks`
40+
*`DeclarationListItem.Name` -->`DeclarationListItem.NameInList`
3841

3942
###F# 6.0 / Visual Studio 17.0
4043

‎src/Compiler/Checking/CheckComputationExpressions.fs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
728728
letcheckForBinaryApp comp=
729729
match compwith
730730
| StripApps(SingleIdent nm,[StripApps(SingleIdent nm2, args); arg2])when
731-
IsMangledInfixOperator nm.idText&&
731+
IsLogicalInfixOpName nm.idText&&
732732
(match tryExpectedArgCountForCustomOperator nm2with Some n-> n>0|_->false)&&
733733
not(List.isEmpty args)->
734734
letestimatedRangeOfIntendedLeftAndRightArguments= unionRanges(List.last args).Range arg2.Range
@@ -876,8 +876,12 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
876876
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither,true, l,(arbExpr(caption, l.Range.EndRange)), l.Range)
877877

878878
letmkOverallExprGivenVarSpaceExpr,varSpaceInner=
879+
879880
letisNullableOp opId=
880-
match DecompileOpName opIdwith"?="|"=?"|"?=?"->true|_->false
881+
match ConvertValLogicalNameToDisplayNameCore opIdwith
882+
|"?="|"=?"|"?=?"->true
883+
|_->false
884+
881885
match secondResultPatOpt, keySelectorsOptwith
882886
// groupJoin
883887
| Some secondResultPat, Some relExprwhen customOperationIsLikeGroupJoin nm->
@@ -889,7 +893,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
889893
| BinOpExpr(opId, l, r)->
890894
if isNullableOp opId.idTextthen
891895
// When we cannot resolve NullableOps, recommend the relevant namespace to be added
892-
errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range))
896+
errorR(Error(FSComp.SR.cannotResolveNullableOperators(ConvertValLogicalNameToDisplayNameCore opId.idText), relExpr.Range))
893897
else
894898
errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range))
895899
letl= wrapInArbErrSequence l"_keySelector1"
@@ -911,7 +915,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
911915
| BinOpExpr(opId, l, r)->
912916
if isNullableOp opId.idTextthen
913917
// When we cannot resolve NullableOps, recommend the relevant namespace to be added
914-
errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range))
918+
errorR(Error(FSComp.SR.cannotResolveNullableOperators(ConvertValLogicalNameToDisplayNameCore opId.idText), relExpr.Range))
915919
else
916920
errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range))
917921
// this is not correct JoinRelation but it is still binary operation

‎src/Compiler/Checking/CheckExpressions.fs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,19 +1339,19 @@ let MakeMemberDataAndMangledNameForMemberVal(g, tcref, isExtrinsic, attrs, implS
13391339
else
13401340
List.foldBack (fun x -> qualifiedMangledNameOfTyconRef (tcrefOfAppTy g x)) intfSlotTys logicalName
13411341

1342-
if not isCompGen &&IsMangledOpName id.idText && IsMangledInfixOperator id.idText then
1342+
if not isCompGen &&IsLogicalInfixOpName id.idText then
13431343
let m = id.idRange
1344-
let name =DecompileOpName id.idText
1344+
let name =ConvertValLogicalNameToDisplayNameCore id.idText
13451345
// Check symbolic members. Expect valSynData implied arity to be [[2]].
13461346
match SynInfo.AritiesOfArgs valSynData with
13471347
| [] | [0] -> warning(Error(FSComp.SR.memberOperatorDefinitionWithNoArguments name, m))
13481348
| n :: otherArgs ->
1349-
let opTakesThreeArgs =IsTernaryOperator name
1349+
let opTakesThreeArgs =IsLogicalTernaryOperator name
13501350
if n<>2 && not opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonPairArgument(name, n), m))
13511351
if n<>3 && opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonTripleArgument(name, n), m))
13521352
if not (isNil otherArgs) then warning(Error(FSComp.SR.memberOperatorDefinitionWithCurriedArguments name, m))
13531353

1354-
if isExtrinsic &&IsMangledOpName id.idText then
1354+
if isExtrinsic &&IsLogicalOpName id.idText then
13551355
warning(Error(FSComp.SR.tcMemberOperatorDefinitionInExtrinsic(), id.idRange))
13561356

13571357
PrelimMemberInfo(memberInfo, logicalName, compiledName)
@@ -1471,7 +1471,7 @@ let CheckForAbnormalOperatorNames (cenv: cenv) (idRange: range) coreDisplayName
14711471
if (idRange.EndColumn - idRange.StartColumn <= 5) &&
14721472
not g.compilingFSharpCore
14731473
then
1474-
let opName =DecompileOpName coreDisplayName
1474+
let opName =ConvertValLogicalNameToDisplayNameCore coreDisplayName
14751475
let isMember = memberInfoOpt.IsSome
14761476
match opName with
14771477
| Relational ->
@@ -4316,7 +4316,7 @@ and TcPseudoMemberSpec cenv newOk env synTypes tpenv synMemberSig m =
43164316
let argTys = List.map fst argTys
43174317
let logicalCompiledName = ComputeLogicalName id memberFlags
43184318

4319-
let item = Item.ArgName (id, memberConstraintTy, None)
4319+
let item = Item.ArgName (Someid, memberConstraintTy, None, id.idRange)
43204320
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights)
43214321

43224322
TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None), tpenv
@@ -4903,7 +4903,7 @@ and TcStaticConstantParameter cenv (env: TcEnv) tpenv kind (StripParenTypes v) i
49034903
let record ttype =
49044904
match idOpt with
49054905
| Some id ->
4906-
let item = Item.ArgName (id, ttype, Some container)
4906+
let item = Item.ArgName (Someid, ttype, Some container, id.idRange)
49074907
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights)
49084908
| _ -> ()
49094909

@@ -5236,7 +5236,7 @@ and TcPatLongIdentActivePatternCase warnOnUpper cenv (env: TcEnv) vFlags patEnv
52365236

52375237
let activePatArgsAsSynExprs = List.map ConvSynPatToSynExpr activePatArgsAsSynPats
52385238

5239-
let activePatResTys = NewInferenceTypes g apinfo.Names
5239+
let activePatResTys = NewInferenceTypes g apinfo.ActiveTags
52405240
let activePatType = apinfo.OverallType g m ty activePatResTys isStructRetTy
52415241

52425242
let delayed =
@@ -8083,8 +8083,8 @@ and TcNameOfExpr cenv env tpenv (synArg: SynExpr) =
80838083
| Some (IdentTrivia.OriginalNotation(text = text))
80848084
| Some (IdentTrivia.OriginalNotationWithParen(text = text)) -> ident(text, result.idRange)
80858085
| _ ->
8086-
ifIsMangledOpName result.idText then
8087-
let demangled =DecompileOpName result.idText
8086+
ifIsLogicalOpName result.idText then
8087+
let demangled =ConvertValLogicalNameToDisplayNameCore result.idText
80888088
if demangled.Length = result.idRange.EndColumn - result.idRange.StartColumn then
80898089
ident(demangled, result.idRange)
80908090
else result
@@ -8386,7 +8386,7 @@ and TcUnionCaseOrExnCaseOrActivePatternResultItemThen cenv overallTy env item tp
83868386
let mkConstrApp, argTys, argNames =
83878387
match item with
83888388
| Item.ActivePatternResult(apinfo, _apOverallTy, n, _) ->
8389-
let aparity = apinfo.Names.Length
8389+
let aparity = apinfo.ActiveTags.Length
83908390
match aparity with
83918391
| 0 | 1 ->
83928392
let mkConstrApp _mArgs = function [arg] -> arg | _ -> error(InternalError("ApplyUnionCaseOrExn", mItem))
@@ -8658,8 +8658,8 @@ and TcCtorItemThen cenv overallTy env item nm minfos tinstEnclosing tpenv mItem
86588658

86598659
and TcImplicitOpItemThen cenv overallTy env id sln tpenv mItem delayed =
86608660
let g = cenv.g
8661-
let isPrefix =IsPrefixOperator id.idText
8662-
let isTernary =IsTernaryOperator id.idText
8661+
let isPrefix =IsLogicalPrefixOperator id.idText
8662+
let isTernary =IsLogicalTernaryOperator id.idText
86638663

86648664
let argData =
86658665
if isPrefix then
@@ -9748,7 +9748,13 @@ and TcMethodApplication
97489748
match assignedArg.NamedArgIdOpt with
97499749
| None -> ()
97509750
| Some id ->
9751-
let item = Item.ArgName (defaultArg assignedArg.CalledArg.NameOpt id, assignedArg.CalledArg.CalledArgumentType, Some(ArgumentContainer.Method finalCalledMethInfo))
9751+
let idOpt = Some (defaultArg assignedArg.CalledArg.NameOpt id)
9752+
let m =
9753+
match assignedArg.CalledArg.NameOpt with
9754+
| Some id -> id.idRange
9755+
| None -> id.idRange
9756+
let container = ArgumentContainer.Method finalCalledMethInfo
9757+
let item = Item.ArgName (idOpt, assignedArg.CalledArg.CalledArgumentType, Some container, m)
97529758
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ad))
97539759

97549760
/// STEP 6. Build the call expression, then adjust for byref-returns, out-parameters-as-tuples, post-hoc property assignments, methods-as-first-class-value,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp