|
| 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 | +``` |