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 stuff

Co-authored-by: Peter Semkin <petersemkin@duck.com>
Co-authored-by: Petr <psfinaki@users.noreply.github.com>
This commit is contained in:
Don Syme 2022-08-02 16:41:39 +02:00 коммит произвёл GitHub
Родитель 2f3a78a399
Коммит eb72891948
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
45 изменённых файлов: 1014 добавлений и 469 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -123,3 +123,5 @@ nCrunchTemp_*
/test.fs
/test.fsx
tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.actual

206
docs/names.md Normal file
Просмотреть файл

@ -0,0 +1,206 @@
---
title: Display names, logical names and compiled names
category: Compiler Internals
categoryindex: 200
index: 350
---
# Names of entities and values in the F# Compiler
The F# tooling distinguishes between the following concepts of "name" for values, union cases, class/record fields and entities:
* Display names as they appear in code
Characteristics:
- For most identifiers, have double backticks, e.g. ` ``Module name with spaces`` `
- For operator names, are short and parenthesized, e.g. `(+)` for the logical name `op_Addition`
- For active patterns, are parenthesized, e.g. `(|A|_|)`
- etc., see exact specification below
Used in:
- Code outputs, e.g. signature files
- Diagnostics (BUG: not consistently the case today)
Current aliases in code:
- `vref.DisplayName`
- `entity.DisplayName`
- `entity.DisplayNameWithStaticParameters`
- `entity.DisplayNameWithStaticParametersAndUnderscoreTypars`
- `minfo.DisplayName`
- `pinfo.DisplayName`
- `einfo.DisplayName`
- etc.
* Display names as they appear in declaration lists, navigation etc.
Characteristics:
- Same as above without the double backticks or parentheses
Current aliases in code:
- `vref.DisplayNameCore`
- `entity.DisplayNameCore`
- `minfo.DisplayNameCore`
- `pinfo.DisplayNameCore`
- `einfo.DisplayNameCore`
- etc.
* Logical names
Characteristics:
- Are used in `TypedTree`, often "canonical"
- Sometimes require extra flags to qualify the meaning of the name
Current aliases in code:
- `vref.LogicalName`
- `entity.LogicalName`
- `minfo.LogicalName`
- `pinfo.PropertyName`
- `einfo.EventName`
- etc.
* Compiled names
Characterists:
- Mark the names that appear in the .NET IL
Current aliases in code:
- `vref.CompiledName`
- `entity.CompiledName`
- etc.
## Specification of all logical names
The following tables loosely characterise the variations in logical names, how
they correspond to F# source constructs and the `SyntaxTree`/`TypedTree` metadata for these.
Entities:
Display name in code | Logical name | Notes
----------------------------|----------------|-------
C | C | type definition
C | C`1 | e.g. generic type, see notes below for variations of display names
M | M | module definition
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
JsonProvider<"foo.json"> | JsonProvider,Schema=\"xyz\" | static parameters, see notes below for variations of display names
Values:
Display name in code | Relation | Logical name | Notes
---------------------|----------|----------------------|------
(+) | <--> | op_Addition |
(+ ) | --> | op_Addition | not reversed
op_Addition | --> | op_Addition | not reversed
(*) | <--> | op_Multiply |
( * ) | --> | op_Multiply | not reversed
op_Multiply | --> | op_Multiply | not reversed
( *+ ) | <--> | op_MultiplyPlus |
( *+ ) | --> | op_MultiplyPlus | not reversed
op_MultiplyPlus | --> | op_MultiplyPlus | not reversed
(+++) | <--> | op_PlusPlusPlus |
op_PlusPlusPlus | --> | op_PlusPlusPlus | not reversed
(%) | <--> | op_Modulus |
op_Modulus | --> | op_Modulus |
(?) | <--> | op_Dynamic | not defined by default, for x?SomeThing
(?<-) | <--> | op_DynamicAssignment | not defined by default, for x?SomeThing <- "a"
(..) | <--> | op_Range | for "3 .. 5"
(.. ..) | <--> | op_RangeStep | for "5 .. -1 .. 3"
or | <--> | or |
mod | <--> | mod |
``let`` | <--> | let | this is a keyword, in code it appears as ``let``
``type`` | <--> | type | this is a keyword, in code it appears as ``type``
base | <--> | base | for IsBaseVal=true only. Base is a keyword, this is a special base val
``base`` | <--> | base | for IsBaseVal=false only. Base is a keyword, this is not a special base val
SomeClass | <--> | .ctor | IsConstructor=true
``.ctor`` | <--> | .ctor | IsConstructor=false, this is only allowed for let-definitions, e.g. let ``.ctor`` x = 1
<not-shown> | <--> | .cctor | IsClassConstructor=true, should never really appear in diagnostics or user-facing output
``.cctor`` | <--> | .cctor | IsClassConstructor=false, this is only allowed for let-definitions, e.g. let ``.cctor`` x = 1
(\|A\|_\|) | <--> | \|A\|_\| |
(\|A \|_ \|) | --> | \|A\|_\| | not reversed
P | <--> | get_P | IsPropertyGetterMethod = true
P | <--> | set_P | IsPropertySetterMethod = true
Other Val constructs less problematic for naming are:
Display name in code | Relation | Logical name | Notes
---------------------|----------|----------------------|------
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
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
\<not-shown\> | <--> | System.IDisposable.Dispose | ImplementedSlotSigs is non-empty, i.e. length 1, should never really appear in diagnostics or user-facing output
Union cases:
Display name in code | Relation | Logical name | Notes
---------------------|----------|----------------------|------
SomeCase | <--> | SomeCase
` ``Case with space`` ` | <--> | Case with space
` ``type`` ` | <--> | type | This is a keyword
(::) | <--> | op_ColonColon | This is the logical name for the cons union case on `FSharpList` only
[] | <--> | op_Nil | This is the logical name for the nil case on `FSharpList` only
Class and record fields, enum cases, active pattern cases, anonymous record fields:
Display name in code | Relation | Logical name | Notes
---------------------|----------|----------------------|------
SomeField | <--> | SomeField
` ``Field with space`` `| <--> | Field with space
` ``type`` ` | <--> | type | This is a keyword
Generic parameters:
Display name in code | Relation | Logical name | Notes
---------------------|----------|----------------------|------
'T | <--> | T
'` ``T T T`` ` | <--> | T T T | BUG: the backticks are not currently added
'` ``type`` ` | <--> | type | This is a keyword, BUG: the backticks are not currently added
## Variations on display names
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.
* `SomeTypeProvider`
- Used for omitting static parameters
- Alias in code: `entity.CompiledName`
* `SomeTypeProvider<...>`
- Used for eliding static parameters
* `SomeTypeProvider<"foo.json">`
- Used for showing static parameters. These can be very large, e.g. entire connection strings, so better to elide or omit.
- Alias in code: `entity.DisplayNameWithStaticParameters`
* `List<_>`
- Used with underscore typars
- Alias in code: `entity.DisplayNameWithStaticParametersAndUnderscoreTypars`
* `Dictionary<'TKey,'TResult>`
- Used with general typars
* Full name
Examples:
- `SomeNamespace.OtherNamespace.SomeType`
- ``` ``Some Namespace With Spaces``.SomeType``` <-- BUG: not double-ticks today
- `SomeEnclosingType<_>.SomeStaticMethod` <-- BUG: the mangled generic type counts are shown today
## Compiled names
The name that appears in the .NET IL.
Affected by:
- `CompiledName` attribute
- some heuristics for generic type parameters
Also the name from signature is generally preferred; if there is any difference, a warning is emitted.
Example of how signature affects compiled names
```fsharp
Foo.fsi
val SomeFunction: x: int -> y: int -> int
Foo.fs
let SomeFunction a b = a + b // compiled name of parameters is x, y - warning emitted
```

Просмотреть файл

@ -35,6 +35,9 @@ These release notes track our current efforts to document changes to the F# proj
* `SynMeasure` was extended with [SynMeasure.Paren](https://fsharp.github.io/fsharp-compiler-docs/reference/fsharp-compiler-syntax-synmeasure.html#Paren) case.
* 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.
* 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.
* `DoesIdentifierNeedBackticks` is removed, it should always be sufficient to call `NormalizeIdentifierBackticks` or else call something in `PrettyNaming`
* `AddBackticksToIdentifierIfNeeded` is removed, it should always be sufficient to call `NormalizeIdentifierBackticks`
* `DeclarationListItem.Name` --> `DeclarationListItem.NameInList`
### F# 6.0 / Visual Studio 17.0

Просмотреть файл

@ -728,7 +728,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
let checkForBinaryApp comp =
match comp with
| StripApps(SingleIdent nm, [StripApps(SingleIdent nm2, args); arg2]) when
IsMangledInfixOperator nm.idText &&
IsLogicalInfixOpName nm.idText &&
(match tryExpectedArgCountForCustomOperator nm2 with Some n -> n > 0 | _ -> false) &&
not (List.isEmpty args) ->
let estimatedRangeOfIntendedLeftAndRightArguments = unionRanges (List.last args).Range arg2.Range
@ -876,8 +876,12 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
SynExpr.Sequential (DebugPointAtSequential.SuppressNeither, true, l, (arbExpr(caption, l.Range.EndRange)), l.Range)
let mkOverallExprGivenVarSpaceExpr, varSpaceInner =
let isNullableOp opId =
match DecompileOpName opId with "?=" | "=?" | "?=?" -> true | _ -> false
match ConvertValLogicalNameToDisplayNameCore opId with
| "?=" | "=?" | "?=?" -> true
| _ -> false
match secondResultPatOpt, keySelectorsOpt with
// groupJoin
| Some secondResultPat, Some relExpr when customOperationIsLikeGroupJoin nm ->
@ -889,7 +893,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
| BinOpExpr (opId, l, r) ->
if isNullableOp opId.idText then
// When we cannot resolve NullableOps, recommend the relevant namespace to be added
errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range))
errorR(Error(FSComp.SR.cannotResolveNullableOperators(ConvertValLogicalNameToDisplayNameCore opId.idText), relExpr.Range))
else
errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range))
let l = wrapInArbErrSequence l "_keySelector1"
@ -911,7 +915,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol
| BinOpExpr (opId, l, r) ->
if isNullableOp opId.idText then
// When we cannot resolve NullableOps, recommend the relevant namespace to be added
errorR(Error(FSComp.SR.cannotResolveNullableOperators(DecompileOpName opId.idText), relExpr.Range))
errorR(Error(FSComp.SR.cannotResolveNullableOperators(ConvertValLogicalNameToDisplayNameCore opId.idText), relExpr.Range))
else
errorR(Error(FSComp.SR.tcInvalidRelationInJoin(nm.idText), relExpr.Range))
// this is not correct JoinRelation but it is still binary operation

Просмотреть файл

@ -1339,19 +1339,19 @@ let MakeMemberDataAndMangledNameForMemberVal(g, tcref, isExtrinsic, attrs, implS
else
List.foldBack (fun x -> qualifiedMangledNameOfTyconRef (tcrefOfAppTy g x)) intfSlotTys logicalName
if not isCompGen && IsMangledOpName id.idText && IsMangledInfixOperator id.idText then
if not isCompGen && IsLogicalInfixOpName id.idText then
let m = id.idRange
let name = DecompileOpName id.idText
let name = ConvertValLogicalNameToDisplayNameCore id.idText
// Check symbolic members. Expect valSynData implied arity to be [[2]].
match SynInfo.AritiesOfArgs valSynData with
| [] | [0] -> warning(Error(FSComp.SR.memberOperatorDefinitionWithNoArguments name, m))
| n :: otherArgs ->
let opTakesThreeArgs = IsTernaryOperator name
let opTakesThreeArgs = IsLogicalTernaryOperator name
if n<>2 && not opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonPairArgument(name, n), m))
if n<>3 && opTakesThreeArgs then warning(Error(FSComp.SR.memberOperatorDefinitionWithNonTripleArgument(name, n), m))
if not (isNil otherArgs) then warning(Error(FSComp.SR.memberOperatorDefinitionWithCurriedArguments name, m))
if isExtrinsic && IsMangledOpName id.idText then
if isExtrinsic && IsLogicalOpName id.idText then
warning(Error(FSComp.SR.tcMemberOperatorDefinitionInExtrinsic(), id.idRange))
PrelimMemberInfo(memberInfo, logicalName, compiledName)
@ -1471,7 +1471,7 @@ let CheckForAbnormalOperatorNames (cenv: cenv) (idRange: range) coreDisplayName
if (idRange.EndColumn - idRange.StartColumn <= 5) &&
not g.compilingFSharpCore
then
let opName = DecompileOpName coreDisplayName
let opName = ConvertValLogicalNameToDisplayNameCore coreDisplayName
let isMember = memberInfoOpt.IsSome
match opName with
| Relational ->
@ -4316,7 +4316,7 @@ and TcPseudoMemberSpec cenv newOk env synTypes tpenv synMemberSig m =
let argTys = List.map fst argTys
let logicalCompiledName = ComputeLogicalName id memberFlags
let item = Item.ArgName (id, memberConstraintTy, None)
let item = Item.ArgName (Some id, memberConstraintTy, None, id.idRange)
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights)
TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None), tpenv
@ -4903,7 +4903,7 @@ and TcStaticConstantParameter cenv (env: TcEnv) tpenv kind (StripParenTypes v) i
let record ttype =
match idOpt with
| Some id ->
let item = Item.ArgName (id, ttype, Some container)
let item = Item.ArgName (Some id, ttype, Some container, id.idRange)
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights)
| _ -> ()
@ -5236,7 +5236,7 @@ and TcPatLongIdentActivePatternCase warnOnUpper cenv (env: TcEnv) vFlags patEnv
let activePatArgsAsSynExprs = List.map ConvSynPatToSynExpr activePatArgsAsSynPats
let activePatResTys = NewInferenceTypes g apinfo.Names
let activePatResTys = NewInferenceTypes g apinfo.ActiveTags
let activePatType = apinfo.OverallType g m ty activePatResTys isStructRetTy
let delayed =
@ -8083,8 +8083,8 @@ and TcNameOfExpr cenv env tpenv (synArg: SynExpr) =
| Some (IdentTrivia.OriginalNotation(text = text))
| Some (IdentTrivia.OriginalNotationWithParen(text = text)) -> ident(text, result.idRange)
| _ ->
if IsMangledOpName result.idText then
let demangled = DecompileOpName result.idText
if IsLogicalOpName result.idText then
let demangled = ConvertValLogicalNameToDisplayNameCore result.idText
if demangled.Length = result.idRange.EndColumn - result.idRange.StartColumn then
ident(demangled, result.idRange)
else result
@ -8386,7 +8386,7 @@ and TcUnionCaseOrExnCaseOrActivePatternResultItemThen cenv overallTy env item tp
let mkConstrApp, argTys, argNames =
match item with
| Item.ActivePatternResult(apinfo, _apOverallTy, n, _) ->
let aparity = apinfo.Names.Length
let aparity = apinfo.ActiveTags.Length
match aparity with
| 0 | 1 ->
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
and TcImplicitOpItemThen cenv overallTy env id sln tpenv mItem delayed =
let g = cenv.g
let isPrefix = IsPrefixOperator id.idText
let isTernary = IsTernaryOperator id.idText
let isPrefix = IsLogicalPrefixOperator id.idText
let isTernary = IsLogicalTernaryOperator id.idText
let argData =
if isPrefix then
@ -9748,7 +9748,13 @@ and TcMethodApplication
match assignedArg.NamedArgIdOpt with
| None -> ()
| Some id ->
let item = Item.ArgName (defaultArg assignedArg.CalledArg.NameOpt id, assignedArg.CalledArg.CalledArgumentType, Some(ArgumentContainer.Method finalCalledMethInfo))
let idOpt = Some (defaultArg assignedArg.CalledArg.NameOpt id)
let m =
match assignedArg.CalledArg.NameOpt with
| Some id -> id.idRange
| None -> id.idRange
let container = ArgumentContainer.Method finalCalledMethInfo
let item = Item.ArgName (idOpt, assignedArg.CalledArg.CalledArgumentType, Some container, m)
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ad))
/// STEP 6. Build the call expression, then adjust for byref-returns, out-parameters-as-tuples, post-hoc property assignments, methods-as-first-class-value,

Просмотреть файл

@ -1689,9 +1689,9 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
match minfos, recdPropSearch, anonRecdPropSearch with
| [], None, None when MemberConstraintIsReadyForStrongResolution csenv traitInfo ->
if tys |> List.exists (isFunTy g) then
return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(DecompileOpName nm), m, m2))
return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenFunction(ConvertValLogicalNameToDisplayNameCore nm), m, m2))
elif tys |> List.exists (isAnyTupleTy g) then
return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(DecompileOpName nm), m, m2))
return! ErrorD (ConstraintSolverError(FSComp.SR.csExpectTypeWithOperatorButGivenTuple(ConvertValLogicalNameToDisplayNameCore nm), m, m2))
else
match nm, argTys with
| "op_Explicit", [argTy] ->
@ -1703,7 +1703,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
match tys with
| [ty] -> NicePrint.minimalStringOfType denv ty
| _ -> tys |> List.map (NicePrint.minimalStringOfType denv) |> String.concat ", "
let opName = DecompileOpName nm
let opName = ConvertValLogicalNameToDisplayNameCore nm
let err =
match opName with
| "?>=" | "?>" | "?<=" | "?<" | "?=" | "?<>"
@ -1757,9 +1757,9 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
if isInstance <> memFlags.IsInstance then
return!
if isInstance then
ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsNotStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (DecompileOpName nm), nm), m, m2 ))
ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsNotStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 ))
else
ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (DecompileOpName nm), nm), m, m2 ))
ErrorD(ConstraintSolverError(FSComp.SR.csMethodFoundButIsStatic((NicePrint.minimalStringOfType denv minfo.ApparentEnclosingType), (ConvertValLogicalNameToDisplayNameCore nm), nm), m, m2 ))
else
do! CheckMethInfoAttributes g m None minfo
return TTraitSolved (minfo, calledMeth.CalledTyArgs)

Просмотреть файл

@ -122,7 +122,7 @@ let ActivePatternElemsOfModuleOrNamespace g (modref: ModuleOrNamespaceRef) : Nam
cacheOptRef mtyp.ActivePatternElemRefLookupTable (fun () ->
mtyp.AllValsAndMembers
|> Seq.collect (ActivePatternElemsOfVal g modref)
|> Seq.fold (fun acc apref -> NameMap.add apref.Name apref acc) Map.empty)
|> Seq.fold (fun acc apref -> NameMap.add apref.LogicalName apref acc) Map.empty)
//---------------------------------------------------------------------------
// Name Resolution Items
@ -228,7 +228,17 @@ type Item =
| ImplicitOp of Ident * TraitConstraintSln option ref
/// Represents the resolution of a name to a named argument
| ArgName of Ident * TType * ArgumentContainer option
//
// In the FCS API, Item.ArgName corresponds to FSharpParameter symbols.
// Not all parameters have names, e.g. for 'g' in this:
//
// let f (g: int -> int) x = ...
//
// then the symbol for 'g' reports FSharpParameters via CurriedParameterGroups
// based on analyzing the type of g as a function type.
//
// For these parameters, the identifier will be missing.
| ArgName of ident: Ident option * argType: TType * container: ArgumentContainer option * range: range
/// Represents the resolution of a name to a named property setter
| SetterArg of Ident * Item
@ -247,21 +257,20 @@ type Item =
member d.DisplayNameCore =
match d with
| Item.Value v -> v.DisplayNameCore
| Item.ActivePatternResult (apinfo, _ty, n, _) -> apinfo.ActiveTags[n]
| Item.ActivePatternCase apref -> apref.Name
| Item.ActivePatternResult (apinfo, _ty, n, _) -> apinfo.DisplayNameCoreByIdx n
| Item.ActivePatternCase apref -> apref.DisplayNameCore
| Item.UnionCase(uinfo, _) -> uinfo.DisplayNameCore
| Item.ExnCase tcref -> tcref.DisplayNameCore
| Item.RecdField rfinfo -> rfinfo.DisplayNameCore
| Item.UnionCaseField (uci, fieldIndex) -> uci.UnionCase.GetFieldByIndex(fieldIndex).DisplayNameCore
| Item.AnonRecdField (anonInfo, _tys, i, _m) -> anonInfo.SortedNames[i]
| Item.AnonRecdField (anonInfo, _tys, fieldIndex, _m) -> anonInfo.DisplayNameCoreByIdx fieldIndex
| Item.NewDef id -> id.idText
| Item.ILField finfo -> finfo.FieldName
| Item.Event einfo -> einfo.EventName
| Item.Property(_, FSProp(_, _, Some v, _) :: _)
| Item.Property(_, FSProp(_, _, _, Some v) :: _) -> v.DisplayNameCore
| Item.Property(nm, _) -> nm |> DecompileOpName
| Item.ILField finfo -> finfo.DisplayNameCore
| Item.Event einfo -> einfo.DisplayNameCore
| Item.Property(_, pinfo :: _) -> pinfo.DisplayNameCore
| Item.Property(nm, _) -> nm |> ConvertValLogicalNameToDisplayNameCore
| Item.MethodGroup(_, FSMeth(_, _, v, _) :: _, _) -> v.DisplayNameCore
| Item.MethodGroup(nm, _, _) -> nm |> DecompileOpName
| Item.MethodGroup(nm, _, _) -> nm |> ConvertValLogicalNameToDisplayNameCore
| Item.CtorGroup(nm, _) -> nm |> DemangleGenericTypeName
| Item.FakeInterfaceCtor (AbbrevOrAppTy tcref)
| Item.DelegateCtor (AbbrevOrAppTy tcref) -> tcref.DisplayNameCore
@ -269,7 +278,8 @@ type Item =
| Item.UnqualifiedType(tcref :: _) -> tcref.DisplayNameCore
| Item.TypeVar (nm, _) -> nm
| Item.ModuleOrNamespaces(modref :: _) -> modref.DisplayNameCore
| Item.ArgName (id, _, _) -> id.idText
| Item.ArgName (Some id, _, _, _) -> id.idText
| Item.ArgName (None, _, _, _) -> ""
| Item.SetterArg (id, _) -> id.idText
| Item.CustomOperation (customOpName, _, _) -> customOpName
| Item.CustomBuilder (nm, _) -> nm
@ -282,14 +292,18 @@ type Item =
| Item.ExnCase tcref -> tcref.DisplayName
| Item.RecdField rfinfo -> rfinfo.DisplayName
| Item.UnionCaseField (uci, fieldIndex) -> uci.UnionCase.GetFieldByIndex(fieldIndex).DisplayName
| Item.Property(_, FSProp(_, _, Some v, _) :: _)
| Item.Property(_, FSProp(_, _, _, Some v) :: _) -> v.DisplayName
| Item.MethodGroup(_, FSMeth(_, _, v, _) :: _, _) -> v.DisplayName
| Item.AnonRecdField (anonInfo, _tys, fieldIndex, _m) -> anonInfo.DisplayNameByIdx fieldIndex
| Item.ActivePatternCase apref -> apref.DisplayName
| Item.Property(_, pinfo :: _) -> pinfo.DisplayName
| Item.Event einfo -> einfo.DisplayName
| Item.MethodGroup(_, minfo :: _, _) -> minfo.DisplayName
| Item.DelegateCtor (AbbrevOrAppTy tcref) -> tcref.DisplayName
| Item.UnqualifiedType(tcref :: _) -> tcref.DisplayName
| Item.ModuleOrNamespaces(modref :: _) -> modref.DisplayName
| Item.TypeVar (nm, _) -> nm
| _ -> d.DisplayNameCore |> ConvertNameToDisplayName
| Item.TypeVar (nm, _) -> nm |> ConvertLogicalNameToDisplayName
| Item.ArgName (Some id, _, _, _) -> id.idText |> ConvertValLogicalNameToDisplayName false
| Item.ArgName (None, _, _, _) -> ""
| _ -> d.DisplayNameCore |> ConvertLogicalNameToDisplayName
let valRefHash (vref: ValRef) =
match vref.TryDeref with
@ -730,7 +744,7 @@ let AddValRefsToActivePatternsNameEnv g ePatItems (vref: ValRef) =
let ePatItems =
(ActivePatternElemsOfValRef g vref, ePatItems)
||> List.foldBack (fun apref tab ->
NameMap.add apref.Name (Item.ActivePatternCase apref) tab)
NameMap.add apref.LogicalName (Item.ActivePatternCase apref) tab)
// Add literal constants to the environment available for resolving items in patterns
let ePatItems =
@ -763,8 +777,8 @@ let AddValRefToNameEnv g nenv (vref: ValRef) =
/// Add a set of active pattern result tags to the environment.
let AddActivePatternResultTagsToNameEnv (apinfo: ActivePatternInfo) nenv apOverallTy m =
if List.isEmpty apinfo.Names then nenv else
let apResultNameList = List.indexed apinfo.Names
if List.isEmpty apinfo.ActiveTags then nenv else
let apResultNameList = List.indexed apinfo.ActiveTags
{ nenv with
eUnqualifiedItems =
(apResultNameList, nenv.eUnqualifiedItems)
@ -1059,7 +1073,7 @@ let ChooseMethInfosForNameEnv g m ty (minfos: MethInfo list) =
|> List.filter (fun minfo ->
not (minfo.IsInstance || minfo.IsClassConstructor || minfo.IsConstructor) && typeEquiv g minfo.ApparentEnclosingType ty &&
not (IsMethInfoPlainCSharpStyleExtensionMember g m isExtTy minfo) &&
not (IsMangledOpName minfo.LogicalName))
not (IsLogicalOpName minfo.LogicalName))
|> List.groupBy (fun minfo -> minfo.LogicalName)
|> List.filter (fun (_, methGroup) -> not methGroup.IsEmpty)
|> List.map (fun (methName, methGroup) -> KeyValuePair(methName, Item.MethodGroup(methName, methGroup, None)))
@ -1804,10 +1818,10 @@ let ItemsAreEffectivelyEqual g orig other =
| Some vref1, Some vref2 -> valRefDefnEq g vref1 vref2
| _ -> false
| Item.ArgName (id1, _, _), Item.ArgName (id2, _, _) ->
(id1.idText = id2.idText && equals id1.idRange id2.idRange)
| Item.ArgName (Some id1, _, _, m1), Item.ArgName (Some id2, _, _, m2) ->
(id1.idText = id2.idText && equals m1 m2)
| Item.ArgName (id, _, _), ValUse vref | ValUse vref, Item.ArgName (id, _, _) ->
| Item.ArgName (Some id, _, _, _), ValUse vref | ValUse vref, Item.ArgName (Some id, _, _, _) ->
((equals id.idRange vref.DefinitionRange || equals id.idRange vref.SigRange) && id.idText = vref.DisplayName)
| Item.AnonRecdField(anon1, _, i1, _), Item.AnonRecdField(anon2, _, i2, _) -> anonInfoEquiv anon1 anon2 && i1 = i2
@ -1845,7 +1859,7 @@ let ItemsAreEffectivelyEqualHash (g: TcGlobals) orig =
| ActivePatternCaseUse (_, _, idx)-> hash idx
| MethodUse minfo -> minfo.ComputeHashCode()
| PropertyUse pinfo -> pinfo.ComputeHashCode()
| Item.ArgName (id, _, _) -> hash id.idText
| Item.ArgName (Some id, _, _, _) -> hash id.idText
| ILFieldUse ilfinfo -> ilfinfo.ComputeHashCode()
| UnionCaseUse ucase -> hash ucase.CaseName
| RecordFieldUse (name, _) -> hash name
@ -1969,7 +1983,7 @@ type TcResultsSinkImpl(tcGlobals, ?sourceText: ISourceText) =
let keyOpt =
match item with
| Item.Value vref -> Some (endPos, vref.DisplayName)
| Item.ArgName (id, _, _) -> Some (endPos, id.idText)
| Item.ArgName (Some id, _, _, _) -> Some (endPos, id.idText)
| _ -> None
match keyOpt with
@ -2862,7 +2876,7 @@ let rec ResolveExprLongIdentPrim sink (ncenv: NameResolver) first fullyQualified
ChooseTyconRefInExpr (ncenv, m, ad, nenv, id, typeNameResInfo, tcrefs)
let implicitOpSearch() =
if IsMangledOpName id.idText then
if IsLogicalOpName id.idText then
success [(ResolutionInfo.Empty, Item.ImplicitOp(id, ref None))]
else
NoResultsOrUsefulErrors

Просмотреть файл

@ -122,7 +122,17 @@ type Item =
| ImplicitOp of Ident * TraitConstraintSln option ref
/// Represents the resolution of a name to a named argument
| ArgName of Ident * TType * ArgumentContainer option
//
// In the FCS API, Item.ArgName corresponds to FSharpParameter symbols.
// Not all parameters have names, e.g. for 'g' in this:
//
// let f (g: int -> int) x = ...
//
// then the symbol for 'g' reports FSharpParameters via CurriedParameterGroups
// based on analyzing the type of g as a function type.
//
// For these parameters, the identifier will be missing.
| ArgName of ident: Ident option * argType: TType * container: ArgumentContainer option * range: range
/// Represents the resolution of a name to a named property setter
| SetterArg of Ident * Item

Просмотреть файл

@ -445,7 +445,7 @@ module PrintIL =
| Some s -> WordL.equals ^^ wordL s
let layoutILEnumCase nm litVal =
let nameL = ConvertNameToDisplayLayout (tagEnum >> wordL) nm
let nameL = ConvertLogicalNameToDisplayLayout (tagEnum >> wordL) nm
WordL.bar ^^ nameL ^^ layoutILFieldInit litVal
module PrintTypes =
@ -796,7 +796,7 @@ module PrintTypes =
(layoutTyparRefWithInfo denv env tp)) |> longConstraintPrefix]
and layoutTraitWithInfo denv env (TTrait(tys, nm, memFlags, argTys, retTy, _)) =
let nameL = ConvertValNameToDisplayLayout false (tagMember >> wordL) nm
let nameL = ConvertValLogicalNameToDisplayLayout false (tagMember >> wordL) nm
if denv.shortConstraints then
WordL.keywordMember ^^ nameL
else
@ -935,7 +935,7 @@ module PrintTypes =
match argInfo.Name, isOptionalArg, isParamArray, tryDestOptionTy g ty with
// Layout an optional argument
| Some id, true, _, ValueSome ty ->
let idL = ConvertValNameToDisplayLayout false (tagParameter >> rightL) id.idText
let idL = ConvertValLogicalNameToDisplayLayout false (tagParameter >> rightL) id.idText
LeftL.questionMark ^^
(idL |> addColonL) ^^
layoutTypeWithInfoAndPrec denv env 2 ty
@ -946,7 +946,7 @@ module PrintTypes =
// Layout a named argument
| Some id, _, isParamArray, _ ->
let idL = ConvertValNameToDisplayLayout false (tagParameter >> wordL) id.idText
let idL = ConvertValLogicalNameToDisplayLayout false (tagParameter >> wordL) id.idText
let prefix =
if isParamArray then
layoutBuiltinAttribute denv g.attrib_ParamArrayAttribute ^^ idL
@ -1063,7 +1063,7 @@ module PrintTypes =
let prettyLayoutOfMemberSig denv (memberToParentInst, nm, methTypars, argInfos, retTy) =
let _, niceMethodTypars, tauL = prettyLayoutOfMemberSigCore denv memberToParentInst (emptyTyparInst, methTypars, argInfos, retTy)
let nameL = ConvertValNameToDisplayLayout false (tagMember >> wordL) nm
let nameL = ConvertValLogicalNameToDisplayLayout false (tagMember >> wordL) nm
let nameL =
if denv.showTyparBinding then
layoutTyparDecls denv nameL true niceMethodTypars
@ -1151,7 +1151,7 @@ module PrintTastMemberOrVals =
nameL
let layoutMemberName (denv: DisplayEnv) (vref: ValRef) niceMethodTypars tagFunction name =
let nameL = ConvertValNameToDisplayLayout vref.IsBaseVal (tagFunction >> mkNav vref.DefinitionRange >> wordL) name
let nameL = ConvertValLogicalNameToDisplayLayout vref.IsBaseVal (tagFunction >> mkNav vref.DefinitionRange >> wordL) name
let nameL =
if denv.showMemberContainers then
layoutTyconRef denv vref.MemberApparentEntity ^^ SepL.dot ^^ nameL
@ -1376,7 +1376,7 @@ module InfoMemberPrinting =
match isParamArray, nmOpt, isOptArg with
// Layout an optional argument
| _, Some id, true ->
let idL = ConvertValNameToDisplayLayout false (tagParameter >> rightL) id.idText
let idL = ConvertValLogicalNameToDisplayLayout false (tagParameter >> rightL) id.idText
let pty = match ptyOpt with ValueSome x -> x | _ -> pty
LeftL.questionMark ^^
(idL |> addColonL) ^^
@ -1388,14 +1388,14 @@ module InfoMemberPrinting =
// Layout a named ParamArray argument
| true, Some id, _ ->
let idL = ConvertValNameToDisplayLayout false (tagParameter >> wordL) id.idText
let idL = ConvertValLogicalNameToDisplayLayout false (tagParameter >> wordL) id.idText
layoutBuiltinAttribute denv denv.g.attrib_ParamArrayAttribute ^^
(idL |> addColonL) ^^
PrintTypes.layoutType denv pty
// Layout a named normal argument
| false, Some id, _ ->
let idL = ConvertValNameToDisplayLayout false (tagParameter >> wordL) id.idText
let idL = ConvertValLogicalNameToDisplayLayout false (tagParameter >> wordL) id.idText
(idL |> addColonL) ^^
PrintTypes.layoutType denv pty
@ -1423,7 +1423,7 @@ module InfoMemberPrinting =
if minfo.IsConstructor then
WordL.keywordNew
else
let idL = ConvertValNameToDisplayLayout false (tagMethod >> tagNavArbValRef minfo.ArbitraryValRef >> wordL) minfo.LogicalName
let idL = ConvertValLogicalNameToDisplayLayout false (tagMethod >> tagNavArbValRef minfo.ArbitraryValRef >> wordL) minfo.LogicalName
WordL.keywordMember ^^
PrintTypes.layoutTyparDecls denv idL true minfo.FormalMethodTypars
@ -1469,7 +1469,7 @@ module InfoMemberPrinting =
if minfo.IsConstructor then
SepL.leftParen
else
let idL = ConvertValNameToDisplayLayout false (tagMethod >> tagNavArbValRef minfo.ArbitraryValRef >> wordL) minfo.LogicalName
let idL = ConvertValLogicalNameToDisplayLayout false (tagMethod >> tagNavArbValRef minfo.ArbitraryValRef >> wordL) minfo.LogicalName
SepL.dot ^^
PrintTypes.layoutTyparDecls denv idL true minfo.FormalMethodTypars ^^
SepL.leftParen
@ -1537,7 +1537,7 @@ module InfoMemberPrinting =
let retTy = pinfo.GetPropertyType(amap, m)
let retTy = if pinfo.IsIndexer then mkFunTy g (mkRefTupledTy g (pinfo.GetParamTypes(amap, m))) retTy else retTy
let retTy, _ = PrettyTypes.PrettifyType g retTy
let nameL = ConvertValNameToDisplayLayout false (tagProperty >> tagNavArbValRef pinfo.ArbitraryValRef >> wordL) pinfo.PropertyName
let nameL = ConvertValLogicalNameToDisplayLayout false (tagProperty >> tagNavArbValRef pinfo.ArbitraryValRef >> wordL) pinfo.PropertyName
let getterSetter =
match pinfo.HasGetter, pinfo.HasSetter with
| true, false ->
@ -1591,7 +1591,7 @@ module TastDefinitionPrinting =
aboveListL (List.map (layoutExtensionMember denv infoReader) vs)
let layoutRecdField prefix isClassDecl denv infoReader (enclosingTcref: TyconRef) (fld: RecdField) =
let lhs = ConvertNameToDisplayLayout (tagRecordField >> mkNav fld.DefinitionRange >> wordL) fld.DisplayNameCore
let lhs = ConvertLogicalNameToDisplayLayout (tagRecordField >> mkNav fld.DefinitionRange >> wordL) fld.DisplayNameCore
let lhs = (if isClassDecl then layoutAccessibility denv fld.Accessibility lhs else lhs)
let lhs = if fld.IsMutable then wordL (tagKeyword "mutable") --- lhs else lhs
let fieldL =
@ -1632,7 +1632,7 @@ module TastDefinitionPrinting =
sepListL WordL.star (List.mapi (layoutUnionOrExceptionField denv infoReader isGenerated enclosingTcref) fields)
let layoutUnionCase denv infoReader prefixL enclosingTcref (ucase: UnionCase) =
let nmL = ConvertNameToDisplayLayout (tagUnionCase >> mkNav ucase.DefinitionRange >> wordL) ucase.Id.idText
let nmL = ConvertLogicalNameToDisplayLayout (tagUnionCase >> mkNav ucase.DefinitionRange >> wordL) ucase.Id.idText
//let nmL = layoutAccessibility denv ucase.Accessibility nmL
let caseL =
match ucase.RecdFields with
@ -1664,7 +1664,7 @@ module TastDefinitionPrinting =
let layoutILFieldInfo denv (infoReader: InfoReader) m (finfo: ILFieldInfo) =
let staticL = if finfo.IsStatic then WordL.keywordStatic else emptyL
let nameL = ConvertNameToDisplayLayout (tagField >> wordL) finfo.FieldName
let nameL = ConvertLogicalNameToDisplayLayout (tagField >> wordL) finfo.FieldName
let typL = layoutType denv (finfo.FieldType(infoReader.amap, m))
let fieldL = staticL ^^ WordL.keywordVal ^^ (nameL |> addColonL) ^^ typL
layoutXmlDocOfILFieldInfo denv infoReader finfo fieldL
@ -1672,7 +1672,7 @@ module TastDefinitionPrinting =
let layoutEventInfo denv (infoReader: InfoReader) m (einfo: EventInfo) =
let amap = infoReader.amap
let staticL = if einfo.IsStatic then WordL.keywordStatic else emptyL
let nameL = ConvertValNameToDisplayLayout false (tagEvent >> tagNavArbValRef einfo.ArbitraryValRef >> wordL) einfo.EventName
let nameL = ConvertValLogicalNameToDisplayLayout false (tagEvent >> tagNavArbValRef einfo.ArbitraryValRef >> wordL) einfo.EventName
let typL = layoutType denv (einfo.GetDelegateType(amap, m))
let overallL = staticL ^^ WordL.keywordMember ^^ (nameL |> addColonL) ^^ typL
layoutXmlDocOfEventInfo denv infoReader einfo overallL
@ -1691,7 +1691,7 @@ module TastDefinitionPrinting =
else
WordL.keywordMember
let nameL = ConvertValNameToDisplayLayout false (tagProperty >> tagNavArbValRef pinfo.ArbitraryValRef >> wordL) pinfo.PropertyName
let nameL = ConvertValLogicalNameToDisplayLayout false (tagProperty >> tagNavArbValRef pinfo.ArbitraryValRef >> wordL) pinfo.PropertyName
let typL = layoutType denv (pinfo.GetPropertyType(amap, m))
let overallL = modifierAndMember ^^ (nameL |> addColonL) ^^ typL
layoutXmlDocOfPropInfo denv infoReader pinfo overallL
@ -1726,7 +1726,7 @@ module TastDefinitionPrinting =
else
None, tagUnknownType
let nameL = ConvertNameToDisplayLayout (tagger >> mkNav tycon.DefinitionRange >> wordL) tycon.DisplayNameCore
let nameL = ConvertLogicalNameToDisplayLayout (tagger >> mkNav tycon.DefinitionRange >> wordL) tycon.DisplayNameCore
let nameL = layoutAccessibility denv tycon.Accessibility nameL
let denv = denv.AddAccessibility tycon.Accessibility
@ -2081,7 +2081,7 @@ module TastDefinitionPrinting =
let layoutExnDefn denv infoReader (exncref: EntityRef) =
let (-*) = if denv.printVerboseSignatures then (-----) else (---)
let exnc = exncref.Deref
let nameL = ConvertNameToDisplayLayout (tagClass >> mkNav exncref.DefinitionRange >> wordL) exnc.DisplayNameCore
let nameL = ConvertLogicalNameToDisplayLayout (tagClass >> mkNav exncref.DefinitionRange >> wordL) exnc.DisplayNameCore
let nameL = layoutAccessibility denv exnc.TypeReprAccessibility nameL
let exnL = wordL (tagKeyword "exception") ^^ nameL // need to tack on the Exception at the right of the name for goto definition
let reprL =
@ -2132,19 +2132,19 @@ module TastDefinitionPrinting =
let headerL =
if mspec.IsNamespace then
// This is a container namespace. We print the header when we get to the first concrete module.
let pathL = path |> List.map (ConvertNameToDisplayLayout (tagNamespace >> wordL))
let pathL = path |> List.map (ConvertLogicalNameToDisplayLayout (tagNamespace >> wordL))
wordL (tagKeyword "namespace") ^^ sepListL SepL.dot pathL
else
// This is a module
let name = path |> List.last
let nameL = ConvertNameToDisplayLayout (tagModule >> mkNav mspec.DefinitionRange >> wordL) name
let nameL = ConvertLogicalNameToDisplayLayout (tagModule >> mkNav mspec.DefinitionRange >> wordL) name
let nameL =
match path with
| [_] ->
nameL
| _ ->
let innerPath = path[..path.Length - 2]
let innerPathL = innerPath |> List.map (ConvertNameToDisplayLayout (tagNamespace >> wordL))
let innerPathL = innerPath |> List.map (ConvertLogicalNameToDisplayLayout (tagNamespace >> wordL))
sepListL SepL.dot innerPathL ^^ SepL.dot ^^ nameL
let modNameL = wordL (tagKeyword "module") ^^ nameL
@ -2324,7 +2324,7 @@ module InferredSigPrinting =
let basicL =
// Check if this namespace contains anything interesting
if isConcreteNamespace def then
let pathL = innerPath |> List.map (fst >> ConvertNameToDisplayLayout (tagNamespace >> wordL))
let pathL = innerPath |> List.map (fst >> ConvertLogicalNameToDisplayLayout (tagNamespace >> wordL))
// This is a container namespace. We print the header when we get to the first concrete module.
let headerL =
wordL (tagKeyword "namespace") ^^ sepListL SepL.dot pathL
@ -2338,7 +2338,7 @@ module InferredSigPrinting =
basicL
else
// This is a module
let nmL = ConvertNameToDisplayLayout (tagModule >> mkNav mspec.DefinitionRange >> wordL) mspec.DisplayNameCore
let nmL = ConvertLogicalNameToDisplayLayout (tagModule >> mkNav mspec.DefinitionRange >> wordL) mspec.DisplayNameCore
let nmL = layoutAccessibility denv mspec.Accessibility nmL
let denv = denv.AddAccessibility mspec.Accessibility
let basic = imdefL denv def

Просмотреть файл

@ -1328,7 +1328,7 @@ let CompilePatternBasic
let discrim' =
match discrim with
| DecisionTreeTest.ActivePatternCase(_pexp, resTys, isStructRetTy, _apatVrefOpt, idx, apinfo) ->
let aparity = apinfo.Names.Length
let aparity = apinfo.ActiveTags.Length
let total = apinfo.IsTotal
if not total && aparity > 1 then
error(Error(FSComp.SR.patcPartialActivePatternsGenerateOneResult(), m))
@ -1410,7 +1410,7 @@ let CompilePatternBasic
// Total active patterns always return choice values
let hasParam = (match apatVrefOpt with None -> true | Some (vref, _) -> doesActivePatternHaveFreeTypars g vref)
if (hasParam && i = iInvestigated) || (discrimsEq g discrim (Option.get (getDiscrimOfPattern patAtActive))) then
let aparity = apinfo.Names.Length
let aparity = apinfo.ActiveTags.Length
let subAccess j tpinst _e' =
assert inpExprOpt.IsSome
if aparity <= 1 then

Просмотреть файл

@ -653,13 +653,13 @@ type MethInfo =
member x.DisplayName =
match x with
| FSMeth(_, _, vref, _) -> vref.DisplayName
| _ -> x.LogicalName |> PrettyNaming.ConvertValNameToDisplayName false
| _ -> x.LogicalName |> PrettyNaming.ConvertValLogicalNameToDisplayName false
/// Get the method name in DisplayName form
member x.DisplayNameCore =
match x with
| FSMeth(_, _, vref, _) -> vref.DisplayNameCore
| _ -> x.LogicalName |> PrettyNaming.DecompileOpName
| _ -> x.LogicalName |> PrettyNaming.ConvertValLogicalNameToDisplayNameCore
/// Indicates if this is a method defined in this assembly with an internal XML comment
member x.HasDirectXmlComment =
@ -1377,6 +1377,8 @@ type ILFieldInfo =
| ProvidedField(_, fi, m) -> fi.PUntaint((fun fi -> fi.Name), m)
#endif
member x.DisplayNameCore = x.FieldName
/// Indicates if the field is readonly (in the .NET/C# sense of readonly)
member x.IsInitOnly =
match x with
@ -1523,14 +1525,14 @@ type UnionCaseInfo =
///
/// Backticks and parens are not added for non-identifiers.
///
/// Note logical names op_Nil and op_ConsCons become [] and :: respectively.
/// Note logical names op_Nil and op_ColonColon become [] and :: respectively.
member x.DisplayNameCore = x.UnionCase.DisplayNameCore
/// Get the display name of the union case
///
/// Backticks and parens are added implicitly for non-identifiers.
///
/// Note logical names op_Nil and op_ConsCons become ([]) and (::) respectively.
/// Note logical names op_Nil and op_ColonColon become ([]) and (::) respectively.
member x.DisplayName = x.UnionCase.DisplayName
/// Get the instantiation of the type parameters of the declaring type of the union case
@ -1696,6 +1698,20 @@ type PropInfo =
#endif
| FSProp _ -> failwith "unreachable"
/// Get the property name in DisplayName form
member x.DisplayName =
match x with
| FSProp(_, _, Some vref, _)
| FSProp(_, _, _, Some vref) -> vref.DisplayName
| _ -> x.PropertyName |> PrettyNaming.ConvertValLogicalNameToDisplayName false
/// Get the property name in DisplayNameCore form
member x.DisplayNameCore =
match x with
| FSProp(_, _, Some vref, _)
| FSProp(_, _, _, Some vref) -> vref.DisplayNameCore
| _ -> x.PropertyName |> PrettyNaming.ConvertValLogicalNameToDisplayNameCore
/// Indicates if this property has an associated getter method.
member x.HasGetter =
match x with
@ -2083,6 +2099,7 @@ type EventInfo =
#if !NO_TYPEPROVIDERS
| ProvidedEvent (amap, ei, m) -> ImportProvidedType amap m (ei.PApply((fun ei -> ei.DeclaringType), m))
#endif
/// Get the enclosing type of the method info, using a nominal type for tuple types
member x.ApparentEnclosingAppType =
match x with
@ -2129,6 +2146,18 @@ type EventInfo =
| ProvidedEvent (_, ei, m) -> ei.PUntaint((fun ei -> ei.Name), m)
#endif
/// Get the event name in DisplayName form
member x.DisplayName =
match x with
| FSEvent (_, p, _, _) -> p.DisplayName
| _ -> x.EventName |> PrettyNaming.ConvertValLogicalNameToDisplayName false
/// Get the event name in DisplayNameCore form
member x.DisplayNameCore =
match x with
| FSEvent (_, p, _, _) -> p.DisplayNameCore
| _ -> x.EventName |> PrettyNaming.ConvertValLogicalNameToDisplayNameCore
/// Indicates if this property is static.
member x.IsStatic =
match x with

Просмотреть файл

@ -552,6 +552,9 @@ type ILFieldInfo =
/// Get the name of the field
member FieldName: string
/// Get the core of the display name for the field. This is the same as the logical name.
member DisplayNameCore: string
/// Get an (uninstantiated) reference to the field as an Abstract IL ILFieldRef
member ILFieldRef: ILFieldRef
@ -648,14 +651,14 @@ type UnionCaseInfo =
///
/// Backticks and parens are not added for non-identifiers.
///
/// Note logical names op_Nil and op_ConsCons become [] and :: respectively.
/// Note logical names op_Nil and op_ColonColon become [] and :: respectively.
member DisplayNameCore: string
/// Get the display name of the union case
///
/// Backticks and parens are added implicitly for non-identifiers.
///
/// Note logical names op_Nil and op_ConsCons become ([]) and (::) respectively.
/// Note logical names op_Nil and op_ColonColon become ([]) and (::) respectively.
member DisplayName: string
/// Get the F# metadata for the declaring union type
@ -838,6 +841,14 @@ type PropInfo =
/// Get the logical name of the property.
member PropertyName: string
/// Get the display name of the property.
///
/// Backticks and parens are added implicitly for non-identifiers.
member DisplayName: string
/// Get the property name in core DisplayName form (no backticks or parens added)
member DisplayNameCore: string
/// Get a MethInfo for the 'setter' method associated with the property
member SetterMethod: MethInfo
@ -942,6 +953,14 @@ type EventInfo =
/// Get the logical name of the event.
member EventName: string
/// Get the display name of the event.
///
/// Backticks and parens are added implicitly for non-identifiers.
member DisplayName: string
/// Get the event name in core DisplayName form (no backticks or parens added)
member DisplayNameCore: string
/// Indicates if this event has an associated XML comment authored in this assembly.
member HasDirectXmlComment: bool

Просмотреть файл

@ -610,7 +610,7 @@ let OutputPhasedErrorR (os: StringBuilder) (diagnostic: PhasedDiagnostic) (canSu
for value in buffer do
os.AppendLine() |> ignore
os.AppendString " "
os.AppendString(DecompileOpName value)
os.AppendString(ConvertValLogicalNameToDisplayNameCore value)
let rec OutputExceptionR (os: StringBuilder) error =
@ -937,12 +937,12 @@ let OutputPhasedErrorR (os: StringBuilder) (diagnostic: PhasedDiagnostic) (canSu
| Duplicate (k, s, _) ->
if k = "member" then
os.AppendString(Duplicate1E().Format(DecompileOpName s))
os.AppendString(Duplicate1E().Format(ConvertValLogicalNameToDisplayNameCore s))
else
os.AppendString(Duplicate2E().Format k (DecompileOpName s))
os.AppendString(Duplicate2E().Format k (ConvertValLogicalNameToDisplayNameCore s))
| UndefinedName (_, k, id, suggestionsF) ->
os.AppendString(k (DecompileOpName id.idText))
os.AppendString(k (ConvertValLogicalNameToDisplayNameCore id.idText))
suggestNames suggestionsF id.idText
| InternalUndefinedItemRef (f, smr, ccuName, s) ->
@ -954,11 +954,11 @@ let OutputPhasedErrorR (os: StringBuilder) (diagnostic: PhasedDiagnostic) (canSu
| FieldsFromDifferentTypes (_, fref1, fref2, _) ->
os.AppendString(FieldsFromDifferentTypesE().Format fref1.FieldName fref2.FieldName)
| VarBoundTwice id -> os.AppendString(VarBoundTwiceE().Format(DecompileOpName id.idText))
| VarBoundTwice id -> os.AppendString(VarBoundTwiceE().Format(ConvertValLogicalNameToDisplayNameCore id.idText))
| Recursion (denv, id, ty1, ty2, _) ->
let ty1, ty2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2
os.AppendString(RecursionE().Format (DecompileOpName id.idText) ty1 ty2 tpcs)
os.AppendString(RecursionE().Format (ConvertValLogicalNameToDisplayNameCore id.idText) ty1 ty2 tpcs)
| InvalidRuntimeCoercion (denv, ty1, ty2, _) ->
let ty1, ty2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2
@ -1648,7 +1648,7 @@ let OutputPhasedErrorR (os: StringBuilder) (diagnostic: PhasedDiagnostic) (canSu
| DiagnosticWithText (_, s, _) -> os.AppendString s
| DiagnosticWithSuggestions (_, s, _, idText, suggestionF) ->
os.AppendString(DecompileOpName s)
os.AppendString(ConvertValLogicalNameToDisplayNameCore s)
suggestNames suggestionF idText
| InternalError (s, _)

Просмотреть файл

@ -549,7 +549,7 @@ type internal TypeCheckInfo
x
|> List.choose (fun (ParamData (_isParamArray, _isInArg, _isOutArg, _optArgInfo, _callerInfo, name, _, ty)) ->
match name with
| Some n -> Some(Item.ArgName(n, ty, Some(ArgumentContainer.Method meth)))
| Some id -> Some(Item.ArgName(Some id, ty, Some(ArgumentContainer.Method meth), id.idRange))
| None -> None)
| _ -> [])

Просмотреть файл

@ -175,7 +175,7 @@ module DeclarationListHelpers =
wordL (tagText (FSComp.SR.typeInfoUnionCase())) ^^
NicePrint.layoutTyconRef denv ucinfo.TyconRef ^^
sepL (tagPunctuation ".") ^^
wordL (tagUnionCase (DecompileOpName uc.Id.idText) |> mkNav uc.DefinitionRange) ^^
wordL (tagUnionCase (ConvertValLogicalNameToDisplayNameCore uc.Id.idText) |> mkNav uc.DefinitionRange) ^^
RightL.colon ^^
(if List.isEmpty recd then emptyL else NicePrint.layoutUnionCases denv infoReader ucinfo.TyconRef recd ^^ WordL.arrow) ^^
NicePrint.layoutType denv unionTy
@ -196,14 +196,13 @@ module DeclarationListHelpers =
// Active pattern tags
| Item.ActivePatternCase apref ->
let v = apref.ActivePatternVal
// Format the type parameters to get e.g. ('a -> 'a) rather than ('?1234 -> '?1234)
let vTauTy = v.TauType
// REVIEW: use _cxs here
let (prettyTyparInst, prettyTy), _cxs = PrettyTypes.PrettifyInstAndType denv.g (item.TyparInstantiation, vTauTy)
let remarks = OutputFullName displayFullName pubpathOfValRef fullDisplayTextOfValRefAsLayout v
let layout =
wordL (tagText (FSComp.SR.typeInfoActiveRecognizer())) ^^
wordL (tagActivePatternCase apref.Name |> mkNav v.DefinitionRange) ^^
wordL (tagActivePatternCase apref.DisplayName |> mkNav v.DefinitionRange) ^^
RightL.colon ^^
NicePrint.layoutType denv prettyTy
@ -224,14 +223,14 @@ module DeclarationListHelpers =
| Item.RecdField rfinfo when rfinfo.TyconRef.IsFSharpException ->
let ty, _ = PrettyTypes.PrettifyType g rfinfo.FieldType
let id = rfinfo.RecdField.Id
let id = rfinfo.DisplayName
let layout =
wordL (tagText (FSComp.SR.typeInfoArgument())) ^^
wordL (tagParameter id.idText) ^^
wordL (tagParameter id) ^^
RightL.colon ^^
NicePrint.layoutType denv ty
let layout = toArray layout
ToolTipElement.Single (layout, xml, paramName = id.idText)
ToolTipElement.Single (layout, xml, paramName = id)
// F# record field names
| Item.RecdField rfinfo ->
@ -430,7 +429,7 @@ module DeclarationListHelpers =
| Item.AnonRecdField(anon, argTys, i, _) ->
let argTy = argTys[i]
let nm = anon.SortedNames[i]
let nm = anon.DisplayNameByIdx i
let argTy, _ = PrettyTypes.PrettifyType g argTy
let layout =
wordL (tagText (FSComp.SR.typeInfoAnonRecdField())) ^^
@ -441,7 +440,7 @@ module DeclarationListHelpers =
ToolTipElement.Single (layout, FSharpXmlDoc.None)
// Named parameters
| Item.ArgName (id, argTy, _) ->
| Item.ArgName (Some id, argTy, _, _) ->
let argTy, _ = PrettyTypes.PrettifyType g argTy
let layout =
wordL (tagText (FSComp.SR.typeInfoArgument())) ^^
@ -655,10 +654,10 @@ module internal DescriptionListsImpl =
// in this case use old approach and return only information about types
getPrettyParamsOfTypes ()
| Some valRefInfo ->
| Some valReprInfo ->
// ValReprInfo will exist for top-level syntactic functions
// per spec: binding is considered to define a syntactic function if it is either a function or its immediate right-hand-side is a anonymous function
let _, argInfos, lastRetTy, _ = GetTopValTypeInFSharpForm g valRefInfo vref.Type m
let _, argInfos, lastRetTy, _ = GetTopValTypeInFSharpForm g valReprInfo vref.Type m
match argInfos with
| [] ->
// handles cases like 'let foo = List.map'
@ -700,7 +699,7 @@ module internal DescriptionListsImpl =
let args, resTy = stripFunTy denv.g vTauTy
let apinfo = Option.get (TryGetActivePatternInfo v)
let aparity = apinfo.Names.Length
let aparity = apinfo.ActiveTags.Length
let caseTy = if aparity <= 1 then resTy else (argsOfAppTy g resTy)[apref.CaseIndex]
@ -918,8 +917,11 @@ module internal DescriptionListsImpl =
[<Sealed>]
type DeclarationListItem(textInDeclList: string, textInCode: string, fullName: string, glyph: FSharpGlyph, info, accessibility: FSharpAccessibility,
kind: CompletionItemKind, isOwnMember: bool, priority: int, isResolved: bool, namespaceToOpen: string option) =
member _.Name = textInDeclList
member _.NameInList = textInDeclList
member _.NameInCode = textInCode
member _.Description =

Просмотреть файл

@ -3,6 +3,7 @@
// API for declaration lists and method overload lists
namespace FSharp.Compiler.EditorServices
open System
open FSharp.Compiler.NameResolution
open FSharp.Compiler.InfoReader
open FSharp.Compiler.Symbols
@ -94,10 +95,21 @@ type internal CompletionItem =
// Note: this type holds a weak reference to compiler resources.
[<Sealed>]
type public DeclarationListItem =
/// Get the text to display in the declaration list for the declaration.
///
/// This is a display name without backticks.
[<Obsolete("Renamed to NameInList - this is the text to appear in the declaration list, while NameInCode is the text inserted on completion.")>]
member Name: string
/// Get the text to display in the declaration list for the declaration.
///
/// This is a display name without backticks.
member NameInList: string
/// Get the text for the declaration as it's to be inserted into source code.
///
/// This is a display name with backticks if necessary.
member NameInCode: string
/// Get the description

Просмотреть файл

@ -1211,12 +1211,6 @@ type FSharpSourceTokenizer(conditionalDefines: string list, fileName: string opt
module FSharpKeywords =
let DoesIdentifierNeedBackticks s =
PrettyNaming.DoesIdentifierNeedBackticks s
let AddBackticksToIdentifierIfNeeded s =
PrettyNaming.AddBackticksToIdentifierIfNeeded s
let NormalizeIdentifierBackticks s =
PrettyNaming.NormalizeIdentifierBackticks s

Просмотреть файл

@ -337,14 +337,8 @@ module internal TestExpose =
val TokenInfo: Parser.token -> FSharpTokenColorKind * FSharpTokenCharKind * FSharpTokenTriggerClass
module FSharpKeywords =
/// Checks if adding backticks to identifier is needed.
val DoesIdentifierNeedBackticks: string -> bool
/// Add backticks if the identifier is a keyword.
/// A utility to help determine if an identifier needs to be quoted, this doesn't quote F# keywords.
val AddBackticksToIdentifierIfNeeded: string -> string
/// Remove backticks if present.
/// Remove backticks if present and not needed.
val NormalizeIdentifierBackticks: string -> string
/// Keywords paired with their descriptions. Used in completion and quick info.

Просмотреть файл

@ -43,7 +43,7 @@ type NavigationEntityKind =
type NavigationItem
(
uniqueName: string,
name: string,
logicalName: string,
kind: NavigationItemKind,
glyph: FSharpGlyph,
range: range,
@ -58,7 +58,7 @@ type NavigationItem
member _.UniqueName = uniqueName
member _.Name = name
member _.LogicalName = logicalName
member _.Glyph = glyph
@ -77,7 +77,7 @@ type NavigationItem
member _.Access = access
member _.WithUniqueName(uniqueName: string) =
NavigationItem(uniqueName, name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access)
NavigationItem(uniqueName, logicalName, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access)
static member Create(name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access) =
NavigationItem("", name, kind, glyph, range, bodyRange, singleTopLevel, enclosingEntityKind, isAbstract, access)
@ -432,18 +432,18 @@ module NavigationImpl =
let nested =
nested
|> Array.ofList
|> Array.map (fun (decl, idx) -> decl.WithUniqueName(uniqueName d.Name idx))
|> Array.map (fun (decl, idx) -> decl.WithUniqueName(uniqueName d.LogicalName idx))
nested |> Array.sortInPlaceWith (fun a b -> compare a.Name b.Name)
nested |> Array.sortInPlaceWith (fun a b -> compare a.LogicalName b.LogicalName)
{
Declaration = d.WithUniqueName(uniqueName d.Name idx)
Declaration = d.WithUniqueName(uniqueName d.LogicalName idx)
Nested = nested
}
|]
items
|> Array.sortInPlaceWith (fun a b -> compare a.Declaration.Name b.Declaration.Name)
|> Array.sortInPlaceWith (fun a b -> compare a.Declaration.LogicalName b.Declaration.LogicalName)
NavigationItems(items)
@ -639,20 +639,22 @@ module NavigationImpl =
let nested =
nested
|> Array.ofList
|> Array.map (fun (decl, idx) -> decl.WithUniqueName(uniqueName d.Name idx))
|> Array.map (fun (decl, idx) -> decl.WithUniqueName(uniqueName d.LogicalName idx))
nested |> Array.sortInPlaceWith (fun a b -> compare a.Name b.Name)
nested |> Array.sortInPlaceWith (fun a b -> compare a.LogicalName b.LogicalName)
let nested = nested |> Array.distinctBy (fun x -> x.Range, x.BodyRange, x.Name, x.Kind)
let nested =
nested
|> Array.distinctBy (fun x -> x.Range, x.BodyRange, x.LogicalName, x.Kind)
{
Declaration = d.WithUniqueName(uniqueName d.Name idx)
Declaration = d.WithUniqueName(uniqueName d.LogicalName idx)
Nested = nested
}
|]
items
|> Array.sortInPlaceWith (fun a b -> compare a.Declaration.Name b.Declaration.Name)
|> Array.sortInPlaceWith (fun a b -> compare a.Declaration.LogicalName b.Declaration.LogicalName)
NavigationItems(items)
@ -692,12 +694,12 @@ type NavigableContainerType =
type NavigableContainer =
{
Type: NavigableContainerType
Name: string
LogicalName: string
}
type NavigableItem =
{
Name: string
LogicalName: string
Range: range
IsSignature: bool
Kind: NavigableItemKind
@ -722,7 +724,7 @@ module NavigateTo =
if not (String.IsNullOrEmpty id.idText) then
let item =
{
Name = id.idText
LogicalName = id.idText
Range = id.idRange
IsSignature = isSignature
Kind = kind
@ -745,7 +747,7 @@ module NavigateTo =
{
Type = NavigableContainerType.Exception
Name = id.idText
LogicalName = id.idText
}
let addComponentInfo containerType kind info isSig container =
@ -757,7 +759,7 @@ module NavigateTo =
{
Type = containerType
Name = formatLongIdent lid
LogicalName = formatLongIdent lid
}
let addValSig kind synValSig isSig container =
@ -825,7 +827,7 @@ module NavigateTo =
item
{
Type = NavigableContainerType.File
Name = fileName
LogicalName = fileName
}
and walkSynModuleOrNamespaceSig (inp: SynModuleOrNamespaceSig) container =
@ -842,7 +844,7 @@ module NavigateTo =
NavigableContainerType.Module
else
NavigableContainerType.Namespace
Name = formatLongIdent lid
LogicalName = formatLongIdent lid
}
for decl in decls do
@ -893,7 +895,7 @@ module NavigateTo =
let container =
{
Type = NavigableContainerType.File
Name = fileName
LogicalName = fileName
}
for item in moduleOrNamespaceList do
@ -913,7 +915,7 @@ module NavigateTo =
NavigableContainerType.Module
else
NavigableContainerType.Namespace
Name = formatLongIdent lid
LogicalName = formatLongIdent lid
}
for decl in decls do

Просмотреть файл

@ -37,7 +37,7 @@ type public NavigationEntityKind =
/// Represents an item to be displayed in the navigation bar
[<Sealed>]
type public NavigationItem =
member Name: string
member LogicalName: string
member UniqueName: string
@ -99,11 +99,17 @@ type NavigableContainerType =
| Exception
type NavigableContainer =
{ Type: NavigableContainerType
Name: string }
{
/// The kind of container.
Type: NavigableContainerType
/// If Type = File, this is the name of the file
/// In other cases it is the logical name of the entity.
LogicalName: string
}
type NavigableItem =
{ Name: string
{ LogicalName: string
Range: range
IsSignature: bool
Kind: NavigableItemKind

Просмотреть файл

@ -108,7 +108,7 @@ module internal SymbolHelpers =
| Item.CtorGroup(_, minfos) -> minfos |> List.tryPick (rangeOfMethInfo g preferFlag)
| Item.ActivePatternResult(APInfo _, _, _, m) -> Some m
| Item.SetterArg (_, item) -> rangeOfItem g preferFlag item
| Item.ArgName (id, _, _) -> Some id.idRange
| Item.ArgName (_, _, _, m) -> Some m
| Item.CustomOperation (_, _, implOpt) -> implOpt |> Option.bind (rangeOfMethInfo g preferFlag)
| Item.ImplicitOp (_, {contents = Some(TraitConstraintSln.FSMethSln(_, vref, _))}) -> Some vref.Range
| Item.ImplicitOp _ -> None
@ -167,7 +167,7 @@ module internal SymbolHelpers =
|> Option.bind ccuOfValRef
|> Option.orElseWith (fun () -> pinfo.DeclaringTyconRef |> computeCcuOfTyconRef))
| Item.ArgName (_, _, Some (ArgumentContainer.Method minfo)) ->
| Item.ArgName (_, _, Some (ArgumentContainer.Method minfo), _) ->
ccuOfMethInfo g minfo
| Item.MethodGroup(_, minfos, _)
@ -180,7 +180,7 @@ module internal SymbolHelpers =
| Item.Types(_, tys) ->
tys |> List.tryPick (tryNiceEntityRefOfTyOption >> Option.bind computeCcuOfTyconRef)
| Item.ArgName (_, _, Some (ArgumentContainer.Type eref)) ->
| Item.ArgName (_, _, Some (ArgumentContainer.Type eref), _) ->
computeCcuOfTyconRef eref
| Item.ModuleOrNamespaces erefs
@ -290,7 +290,7 @@ module internal SymbolHelpers =
| Item.CtorGroup(_, minfo :: _) ->
mkXmlComment (GetXmlDocSigOfMethInfo infoReader m minfo)
| Item.ArgName(_, _, Some argContainer) ->
| Item.ArgName(_, _, Some argContainer, _) ->
match argContainer with
| ArgumentContainer.Method minfo -> mkXmlComment (GetXmlDocSigOfMethInfo infoReader m minfo)
| ArgumentContainer.Type tcref -> mkXmlComment (GetXmlDocSigOfEntityRef infoReader m tcref)
@ -494,10 +494,10 @@ module internal SymbolHelpers =
| Item.ImplicitOp(_, { contents = Some(TraitConstraintSln.FSMethSln(_, vref, _)) })
| Item.Value vref | Item.CustomBuilder (_, vref) -> fullDisplayTextOfValRef vref
| Item.UnionCase (ucinfo, _) -> fullDisplayTextOfUnionCaseRef ucinfo.UnionCaseRef
| Item.ActivePatternResult(apinfo, _ty, idx, _) -> apinfo.Names[idx]
| Item.ActivePatternCase apref -> FullNameOfItem g (Item.Value apref.ActivePatternVal) + "." + apref.Name
| Item.ActivePatternResult(apinfo, _ty, idx, _) -> apinfo.DisplayNameByIdx idx
| Item.ActivePatternCase apref -> FullNameOfItem g (Item.Value apref.ActivePatternVal) + "." + apref.DisplayName
| Item.ExnCase ecref -> fullDisplayTextOfExnRef ecref
| Item.AnonRecdField(anon, _argTys, i, _) -> anon.SortedNames[i]
| Item.AnonRecdField(anon, _argTys, i, _) -> anon.DisplayNameByIdx i
| Item.RecdField rfinfo -> fullDisplayTextOfRecdFieldRef rfinfo.RecdFieldRef
| Item.NewDef id -> id.idText
| Item.ILField finfo -> buildString (fun os -> NicePrint.outputType denv os finfo.ApparentEnclosingType; bprintf os ".%s" finfo.FieldName)
@ -517,8 +517,8 @@ module internal SymbolHelpers =
| Item.ModuleOrNamespaces(modref :: _ as modrefs) ->
let definiteNamespace = modrefs |> List.forall (fun modref -> modref.IsNamespace)
if definiteNamespace then fullDisplayTextOfModRef modref else modref.DisplayName
| Item.TypeVar (id, _) -> id
| Item.ArgName (id, _, _) -> id.idText
| Item.TypeVar _
| Item.ArgName _ -> item.DisplayName
| Item.SetterArg (_, item) -> FullNameOfItem g item
| Item.ImplicitOp(id, _) -> id.idText
| Item.UnionCaseField (UnionCaseInfo (_, ucref), fieldIndex) -> ucref.FieldByIndex(fieldIndex).DisplayName
@ -583,7 +583,7 @@ module internal SymbolHelpers =
else
GetXmlCommentForItemAux None infoReader m item
| Item.ArgName (_, _, argContainer) ->
| Item.ArgName (_, _, argContainer, _) ->
let xmldoc =
match argContainer with
| Some(ArgumentContainer.Method minfo) ->

Просмотреть файл

@ -316,8 +316,8 @@ type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> C
| Item.ActivePatternResult (apinfo, ty, n, _) ->
FSharpActivePatternCase(cenv, apinfo, ty, n, None, item) :> _
| Item.ArgName(id, ty, argOwner) ->
FSharpParameter(cenv, id, ty, argOwner) :> _
| Item.ArgName(id, ty, argOwner, m) ->
FSharpParameter(cenv, id, ty, argOwner, m) :> _
| Item.ImplicitOp(_, { contents = Some(TraitConstraintSln.FSMethSln(_, vref, _)) }) ->
FSharpMemberOrFunctionOrValue(cenv, V vref, item) :> _
@ -1298,7 +1298,7 @@ type FSharpActivePatternGroup(cenv, apinfo:ActivePatternInfo, ty, valOpt) =
member _.Name = valOpt |> Option.map (fun vref -> vref.LogicalName)
member _.Names = makeReadOnlyCollection apinfo.Names
member _.Names = makeReadOnlyCollection apinfo.ActiveTags
member _.IsTotal = apinfo.IsTotal
@ -2025,7 +2025,14 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
// INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for
// either .NET or F# parameters
let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] }
yield FSharpParameter(cenv, pty, argInfo, None, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional, false) ]
let m =
match nmOpt with
| Some v -> v.idRange
| None ->
defaultArg x.DeclarationLocationOpt range0
yield FSharpParameter(cenv, pty, argInfo, None, m, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional, false) ]
|> makeReadOnlyCollection ]
|> makeReadOnlyCollection
@ -2037,7 +2044,13 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
// INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for
// either .NET or F# parameters
let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] }
yield FSharpParameter(cenv, pty, argInfo, None, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional, false) ]
let m =
match nmOpt with
| Some v -> v.idRange
| None ->
defaultArg x.DeclarationLocationOpt range0
yield FSharpParameter(cenv, pty, argInfo, None, m, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional, false) ]
|> makeReadOnlyCollection ]
|> makeReadOnlyCollection
@ -2052,9 +2065,10 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
if isRefTupleTy cenv.g ty
then tryDestRefTupleTy cenv.g ty
else [ty]
let m = defaultArg x.DeclarationLocationOpt range0
yield
allArguments
|> List.map (fun arg -> FSharpParameter(cenv, arg, ValReprInfo.unnamedTopArg1, x.DeclarationLocationOpt))
|> List.map (fun arg -> FSharpParameter(cenv, arg, ValReprInfo.unnamedTopArg1, m))
|> makeReadOnlyCollection ]
|> makeReadOnlyCollection
else makeReadOnlyCollection []
@ -2069,40 +2083,51 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
let isInArg = HasFSharpAttribute cenv.g cenv.g.attrib_InAttribute argInfo.Attribs && isByrefTy cenv.g argTy
let isOutArg = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute argInfo.Attribs && isByrefTy cenv.g argTy
let isOptionalArg = HasFSharpAttribute cenv.g cenv.g.attrib_OptionalArgumentAttribute argInfo.Attribs
yield FSharpParameter(cenv, argTy, argInfo, None, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg, false) ]
let m =
match argInfo.Name with
| Some v -> v.idRange
| None -> defaultArg x.DeclarationLocationOpt range0
yield FSharpParameter(cenv, argTy, argInfo, None, m, isParamArrayArg, isInArg, isOutArg, isOptionalArg, false) ]
|> makeReadOnlyCollection ]
|> makeReadOnlyCollection
member x.ReturnParameter =
checkIsResolved()
match d with
| E e ->
| E einfo ->
// INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods
let m = defaultArg x.DeclarationLocationOpt range0
let retTy =
try PropTypeOfEventInfo cenv.infoReader range0 AccessibleFromSomewhere e
try PropTypeOfEventInfo cenv.infoReader m AccessibleFromSomewhere einfo
with _ ->
// For non-standard events, just use the delegate type as the ReturnParameter type
e.GetDelegateType(cenv.amap, range0)
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt)
einfo.GetDelegateType(cenv.amap, m)
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, m)
| P p ->
| P pinfo ->
// INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods
let retTy = p.GetPropertyType(cenv.amap, range0)
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt)
| M m | C m ->
let m = defaultArg x.DeclarationLocationOpt range0
let retTy = pinfo.GetPropertyType(cenv.amap, m)
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, m)
| M minfo | C minfo ->
// INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods
let retTy = m.GetFSharpReturnType(cenv.amap, range0, m.FormalMethodInst)
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt)
let m = defaultArg x.DeclarationLocationOpt range0
let retTy = minfo.GetFSharpReturnType(cenv.amap, m, minfo.FormalMethodInst)
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, m)
| V v ->
match v.ValReprInfo with
| None ->
let _, tau = v.GeneralizedType
let _argTysl, retTy = stripFunTy cenv.g tau
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, x.DeclarationLocationOpt)
let m = defaultArg x.DeclarationLocationOpt range0
FSharpParameter(cenv, retTy, ValReprInfo.unnamedRetVal, m)
| Some (ValReprInfo(_typars, argInfos, retInfo)) ->
let tau = v.TauType
let _c, retTy = GetTopTauTypeInFSharpForm cenv.g argInfos tau range0
FSharpParameter(cenv, retTy, retInfo, x.DeclarationLocationOpt)
let m = defaultArg x.DeclarationLocationOpt range0
let _c, retTy = GetTopTauTypeInFSharpForm cenv.g argInfos tau m
FSharpParameter(cenv, retTy, retInfo, m)
override _.Attributes =
@ -2293,8 +2318,9 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
let paramTy = GenWitnessTy cenv.g witnessInfo
let nm = String.uncapitalize witnessInfo.MemberName
let nm = if used.Contains nm then nm + string i else nm
let argReprInfo : ArgReprInfo = { Attribs=[]; Name=Some (mkSynId x.DeclarationLocation nm) }
let p = FSharpParameter(cenv, paramTy, argReprInfo, None, None, false, false, false, false, true)
let m = x.DeclarationLocation
let argReprInfo : ArgReprInfo = { Attribs=[]; Name=Some (mkSynId m nm) }
let p = FSharpParameter(cenv, paramTy, argReprInfo, None, m, false, false, false, false, true)
p, (used.Add nm, i + 1))
|> fst
let witnessMethName = ExtraWitnessMethodName x.CompiledName
@ -2389,7 +2415,7 @@ type FSharpType(cenv, ty:TType) =
member _.ProvidedArguments =
let typeName, argNamesAndValues =
try
PrettyNaming.demangleProvidedTypeName typeLogicalName
PrettyNaming.DemangleProvidedTypeName typeLogicalName
with PrettyNaming.InvalidMangledStaticArg piece ->
error(Error(FSComp.SR.etProvidedTypeReferenceInvalidText(piece), range0))
*)
@ -2598,7 +2624,8 @@ type FSharpStaticParameter(cenv, sp: Tainted< TypeProviders.ProvidedParameterInf
protect <| fun () ->
let paramTy = Import.ImportProvidedType cenv.amap m (sp.PApply((fun x -> x.ParameterType), m))
let nm = sp.PUntaint((fun p -> p.Name), m)
Item.ArgName((mkSynId m nm, paramTy, None))),
let id = mkSynId m nm
Item.ArgName(Some id, paramTy, None, m)),
(fun _ _ _ -> true))
member _.Name =
@ -2634,39 +2661,29 @@ type FSharpStaticParameter(cenv, sp: Tainted< TypeProviders.ProvidedParameterInf
"static parameter " + x.Name
#endif
type FSharpParameter(cenv, paramTy: TType, topArgInfo: ArgReprInfo, ownerOpt, ownerRangeOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg, isWitnessArg) =
type FSharpParameter(cenv, paramTy: TType, topArgInfo: ArgReprInfo, ownerOpt, m: range, isParamArrayArg, isInArg, isOutArg, isOptionalArg, isWitnessArg) =
inherit FSharpSymbol(cenv,
(fun () ->
let m = defaultArg ownerRangeOpt range0
let id = match topArgInfo.Name with | Some id -> id | None -> mkSynId m ""
Item.ArgName(id, paramTy, ownerOpt)),
(fun () -> Item.ArgName(topArgInfo.Name, paramTy, ownerOpt, m)),
(fun _ _ _ -> true))
new (cenv, id, ty, container) =
let argInfo: ArgReprInfo = { Name = Some id; Attribs = [] }
FSharpParameter(cenv, ty, argInfo, container, None, false, false, false, false, false)
new (cenv, idOpt, ty, ownerOpt, m) =
let argInfo: ArgReprInfo = { Name = idOpt; Attribs = [] }
FSharpParameter(cenv, ty, argInfo, ownerOpt, m, false, false, false, false, false)
new (cenv, ty, argInfo: ArgReprInfo, ownerRangeOpt) =
FSharpParameter(cenv, ty, argInfo, None, ownerRangeOpt, false, false, false, false, false)
new (cenv, ty, argInfo: ArgReprInfo, m: range) =
FSharpParameter(cenv, ty, argInfo, None, m, false, false, false, false, false)
member _.Name = match topArgInfo.Name with None -> None | Some v -> Some v.idText
member _.cenv: SymbolEnv = cenv
member _.AdjustType ty = FSharpParameter(cenv, ty, topArgInfo, ownerOpt, ownerRangeOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg, isWitnessArg)
member _.AdjustType ty = FSharpParameter(cenv, ty, topArgInfo, ownerOpt, m, isParamArrayArg, isInArg, isOutArg, isOptionalArg, isWitnessArg)
member _.Type: FSharpType = FSharpType(cenv, paramTy)
member _.V = paramTy
member _.DeclarationLocation =
match topArgInfo.Name with
| Some v -> v.idRange
| None ->
match ownerRangeOpt with
| Some m -> m
| None -> range0
member _.DeclarationLocation = m
member _.Owner =
match ownerOpt with

Просмотреть файл

@ -106,6 +106,8 @@ type FSharpSymbol =
member DisplayNameCore: string
/// Gets the display name for the symbol. Double backticks are added if the name is not a valid identifier.
///
/// For FSharpParameter symbols without a name for the paramater, this returns "````"
member DisplayName: string
/// Get the implementation location for the symbol if it was declared in a signature that has an implementation

Просмотреть файл

@ -358,7 +358,7 @@ let IsOperatorDisplayName (name: string) =
//IsOperatorDisplayName "( )" // false
//IsOperatorDisplayName "( +)" // false
let IsMangledOpName (name: string) = name.StartsWithOrdinal(opNamePrefix)
let IsPossibleOpName (name: string) = name.StartsWithOrdinal(opNamePrefix)
/// Compiles a custom operator into a mangled operator name.
/// For example, "!%" becomes "op_DereferencePercent".
@ -432,7 +432,7 @@ let CompileOpName op =
/// For example, "op_DereferencePercent" becomes "!%".
/// This function should only be used for mangled names of custom operators
/// if a mangled name potentially represents a built-in operator,
/// use the 'DecompileOpName' function instead.
/// use the 'ConvertValLogicalNameToDisplayNameCore' function instead.
let decompileCustomOpName =
// Memoize this operation. Custom operators are typically used more than once
// so this avoids repeating decompilation.
@ -510,11 +510,11 @@ let standardOpsDecompile =
ops
let DecompileOpName opName =
let ConvertValLogicalNameToDisplayNameCore opName =
match standardOpsDecompile.TryGetValue opName with
| true, res -> res
| false, _ ->
if IsMangledOpName opName then
if IsPossibleOpName opName then
decompileCustomOpName opName
else
opName
@ -545,15 +545,15 @@ let NormalizeIdentifierBackticks (name: string) : string =
AddBackticksToIdentifierIfNeeded s
let ConvertNameToDisplayName name = AddBackticksToIdentifierIfNeeded name
let ConvertLogicalNameToDisplayName name = AddBackticksToIdentifierIfNeeded name
let ConvertValNameToDisplayName isBaseVal name =
let ConvertValLogicalNameToDisplayName isBaseVal name =
if isBaseVal && name = "base" then
"base"
elif IsUnencodedOpName name || IsMangledOpName name || IsActivePatternName name then
let nm = DecompileOpName name
elif IsUnencodedOpName name || IsPossibleOpName name || IsActivePatternName name then
let nm = ConvertValLogicalNameToDisplayNameCore name
// Check for no decompilation, e.g. op_Implicit, op_NotAMangledOpName, op_A-B
if IsMangledOpName name && (nm = name) then
if IsPossibleOpName name && (nm = name) then
AddBackticksToIdentifierIfNeeded nm
// Add parentheses for multiply-like symbols, with spacing to avoid confusion with comments
elif nm <> "*" && (nm.StartsWithOrdinal "*" || nm.EndsWithOrdinal "*") then
@ -562,23 +562,23 @@ let ConvertValNameToDisplayName isBaseVal name =
else
"(" + nm + ")"
else
ConvertNameToDisplayName name
ConvertLogicalNameToDisplayName name
let ConvertNameToDisplayLayout nonOpLayout name =
let ConvertLogicalNameToDisplayLayout nonOpLayout name =
if DoesIdentifierNeedBackticks name then
leftL (TaggedText.tagPunctuation "``")
^^ wordL (TaggedText.tagOperator name) ^^ rightL (TaggedText.tagPunctuation "``")
else
nonOpLayout name
let ConvertValNameToDisplayLayout isBaseVal nonOpLayout name =
let ConvertValLogicalNameToDisplayLayout isBaseVal nonOpLayout name =
if isBaseVal && name = "base" then
nonOpLayout "base"
elif IsUnencodedOpName name || IsMangledOpName name || IsActivePatternName name then
let nm = DecompileOpName name
elif IsUnencodedOpName name || IsPossibleOpName name || IsActivePatternName name then
let nm = ConvertValLogicalNameToDisplayNameCore name
// Check for no decompilation, e.g. op_Implicit, op_NotAMangledOpName, op_A-B
if IsMangledOpName name && (nm = name) then
ConvertNameToDisplayLayout nonOpLayout name
if IsPossibleOpName name && (nm = name) then
ConvertLogicalNameToDisplayLayout nonOpLayout name
elif nm.StartsWithOrdinal "*" || nm.EndsWithOrdinal "*" then
wordL (TaggedText.tagPunctuation "(")
^^ wordL (TaggedText.tagOperator nm) ^^ wordL (TaggedText.tagPunctuation ")")
@ -586,9 +586,9 @@ let ConvertValNameToDisplayLayout isBaseVal nonOpLayout name =
leftL (TaggedText.tagPunctuation "(")
^^ wordL (TaggedText.tagOperator nm) ^^ rightL (TaggedText.tagPunctuation ")")
elif name = "get_Zero" then
ConvertNameToDisplayLayout nonOpLayout "Zero"
ConvertLogicalNameToDisplayLayout nonOpLayout "Zero"
else
ConvertNameToDisplayLayout nonOpLayout name
ConvertLogicalNameToDisplayLayout nonOpLayout name
let opNameCons = CompileOpName "::"
@ -656,12 +656,16 @@ let IsValidPrefixOperatorDefinitionName s =
| '!' -> s <> "!="
| _ -> false
let IsPrefixOperator s =
if String.IsNullOrEmpty s then
let IsLogicalPrefixOperator logicalName =
if String.IsNullOrEmpty logicalName then
false
else
let s = DecompileOpName s
IsValidPrefixOperatorDefinitionName s
let displayName = ConvertValLogicalNameToDisplayNameCore logicalName
displayName <> logicalName && IsValidPrefixOperatorDefinitionName displayName
let IsLogicalTernaryOperator logicalName =
let displayName = ConvertValLogicalNameToDisplayNameCore logicalName
displayName <> logicalName && (displayName = qmarkSet)
let IsPunctuation s =
if String.IsNullOrEmpty s then
@ -688,8 +692,6 @@ let IsPunctuation s =
| ">]" -> true
| _ -> false
let IsTernaryOperator s = (DecompileOpName s = qmarkSet)
/// EQUALS, INFIX_COMPARE_OP, LESS, GREATER
let relational = [| "="; "!="; "<"; ">"; "$" |]
@ -712,8 +714,8 @@ let ignoredChars = [| '.'; '?' |]
// The lexer defines the strings that lead to those tokens.
//------
// This function recognises these "infix operator" names.
let IsMangledInfixOperator mangled = (* where mangled is assumed to be a compiled name *)
let s = DecompileOpName mangled
let IsLogicalInfixOpName logicalName =
let s = ConvertValLogicalNameToDisplayNameCore logicalName
let skipIgnoredChars = s.TrimStart(ignoredChars)
let afterSkipStartsWith prefix =
@ -723,7 +725,7 @@ let IsMangledInfixOperator mangled = (* where mangled is assumed to be a compile
Array.exists afterSkipStartsWith prefixes
// The following conditions follow the declExpr infix clauses.
// The test corresponds to the lexer definition for the token.
s <> mangled
s <> logicalName
&& ((s = // COLON_EQUALS
":=")
||
@ -744,6 +746,10 @@ let IsMangledInfixOperator mangled = (* where mangled is assumed to be a compile
||
// COLON_COLON
(s = "::")
|| (s = qmark)
|| (s = qmarkSet)
|| (s = parenGet)
|| (s = parenSet)
||
// PLUS_MINUS_OP, MINUS
afterSkipStarts plusMinus
@ -754,6 +760,11 @@ let IsMangledInfixOperator mangled = (* where mangled is assumed to be a compile
// INFIX_STAR_STAR_OP
(s = "**"))
let IsLogicalOpName (logicalName: string) =
IsLogicalPrefixOperator logicalName
|| IsLogicalInfixOpName logicalName
|| IsLogicalTernaryOperator logicalName
let (|Control|Equality|Relational|Indexer|FixedTypes|Other|) opName =
match opName with
| "&"
@ -965,7 +976,7 @@ let ActivePatternInfoOfValName nm (m: range) =
[ (nm, m1) ]
let nm = DecompileOpName nm
let nm = ConvertValLogicalNameToDisplayNameCore nm
if IsActivePatternName nm then
// Skip the '|' at each end when recovering ranges
@ -999,7 +1010,7 @@ let tryDemangleStaticStringArg (mangledText: string) =
exception InvalidMangledStaticArg of string
/// Demangle the static parameters
let demangleProvidedTypeName (typeLogicalName: string) =
let DemangleProvidedTypeName (typeLogicalName: string) =
if typeLogicalName.Contains "," then
let pieces = splitAroundQuotation typeLogicalName ','
@ -1016,7 +1027,7 @@ let demangleProvidedTypeName (typeLogicalName: string) =
typeLogicalName, [||]
/// Mangle the static parameters for a provided type or method
let mangleProvidedTypeName (typeLogicalName, nonDefaultArgs) =
let MangleProvidedTypeName (typeLogicalName, nonDefaultArgs) =
let nonDefaultArgsText =
nonDefaultArgs |> Array.map mangleStaticStringArg |> String.concat ","
@ -1026,7 +1037,7 @@ let mangleProvidedTypeName (typeLogicalName, nonDefaultArgs) =
typeLogicalName + "," + nonDefaultArgsText
/// Mangle the static parameters for a provided type or method
let computeMangledNameWithoutDefaultArgValues (nm, staticArgs, defaultArgValues) =
let ComputeMangledNameWithoutDefaultArgValues (nm, staticArgs, defaultArgValues) =
let nonDefaultArgs =
(staticArgs, defaultArgValues)
||> Array.zip
@ -1037,7 +1048,7 @@ let computeMangledNameWithoutDefaultArgValues (nm, staticArgs, defaultArgValues)
| Some v when v = actualArgValue -> None
| _ -> Some(defaultArgName, actualArgValue))
mangleProvidedTypeName (nm, nonDefaultArgs)
MangleProvidedTypeName(nm, nonDefaultArgs)
let outArgCompilerGeneratedName = "outArg"

Просмотреть файл

@ -28,7 +28,12 @@ val internal opNamePrefix: string = "op_"
/// ..
val IsOperatorDisplayName: name: string -> bool
/// Is the name a valid F# identifier
/// Is the name a valid F# identifier, primarily used internally in PrettyNaming.fs for determining if an
/// identifier needs backticks.
///
/// In general do not use this routine. It is only used in one quick fix, for determining if it is valid
/// to add "_" in front of an identifier.
///
/// A --> true
/// A' --> true
/// _A --> true
@ -36,6 +41,10 @@ val IsOperatorDisplayName: name: string -> bool
/// |A|B| --> false
/// op_Addition --> true
/// + --> false
/// let --> false
/// base --> false
///
/// TBD: needs unit testing
val IsIdentifierName: name: string -> bool
/// Determines if the specified name is a valid name for an active pattern.
@ -45,16 +54,10 @@ val IsIdentifierName: name: string -> bool
/// | --> false
/// || --> false
/// op_Addition --> false
///
/// TBD: needs unit testing
val IsActivePatternName: name: string -> bool
/// Returns `true` if given string requires double backticks to be a valid identifier, e.g.
/// + true, e.g. ``+`` (this is not op_Addition)
/// |>> true, e.g. ``|>>`` (this is not op_Addition)
/// A-B true, e.g. ``A-B``
/// AB false, e.g. AB
/// |A|_| false // this is an active pattern name, needs parens not backticks
val DoesIdentifierNeedBackticks: name: string -> bool
/// Adds double backticks if necessary to make a valid identifier, e.g.
/// op_Addition --> op_Addition
/// + --> ``+`` (this is not op_Addition)
@ -62,40 +65,63 @@ val DoesIdentifierNeedBackticks: name: string -> bool
/// A-B --> ``A-B``
/// AB --> AB
/// |A|_| --> |A|_| this is an active pattern name, needs parens not backticks
val AddBackticksToIdentifierIfNeeded: name: string -> string
/// Removes double backticks if not necessary to make a valid identifier, e.g.
/// ``A`` --> A
/// ``A-B`` --> ``A-B``
val NormalizeIdentifierBackticks: name: string -> string
/// Is the name a mangled operator name (approximate)
/// op_Addition - yes
/// op_Quack - yes
val IsMangledOpName: name: string -> bool
/// Is the name a logical operator name, including unary, binary and ternary operators
/// op_UnaryPlus - yes
/// op_Addition - yes
/// op_Range - yes (?)
/// op_RangeStep - yes (?)
/// op_DynamicAssignment - yes
/// op_Quack - no
/// + - no
/// ABC - no
/// ABC DEF - no
/// base - no
/// |A|_| - no
val IsLogicalOpName: logicalName: string -> bool
/// Compiles an operator into a mangled operator name. For example,
/// Converts the core of an operator name into a logical name. For example,
/// + --> op_Addition
/// !% --> op_DereferencePercent
/// Only used on actual operator names
val CompileOpName: string -> string
/// Decompiles a potentially-mangled operator name back into a display name. For example:
/// Foo --> Foo
/// + --> +
/// op_Addition --> +
/// op_DereferencePercent --> !%
/// A-B --> A-B
/// |A|_| --> |A|_|
/// Used on names of all kinds
val DecompileOpName: string -> string
val CompileOpName: op: string -> string
/// Take a core display name (e.g. "List" or "Strange module name") and convert it to display text
/// by adding backticks if necessary.
/// Foo --> Foo
/// + --> ``+``
/// A-B --> ``A-B``
val internal ConvertNameToDisplayName: name: string -> string
val internal ConvertLogicalNameToDisplayName: name: string -> string
/// Converts the logical name for and operator back into the core of a display name. For example:
/// Foo --> Foo
/// + --> +
/// op_Addition --> +
/// op_DereferencePercent --> !%
/// A-B --> A-B
/// |A|_| --> |A|_|
/// base --> base regardless of IsBaseVal
/// Used on names of all kinds
///
/// TODO: We should assess uses of this function.
///
/// In any cases it is used it probably indicates that text is being
/// generated which:
/// 1. does not contain double-backticks for non-identifiers
/// 2. does not put parentheses arounf operators or active pattern names
///
/// If the text is immediately in quotes, this is generally ok, e.g.
///
/// error FS0038: '+' is bound twice in this pattern
/// error FS0038: '|A|_|' is bound twice in this pattern
/// error FS0038: 'a a' is bound twice in this pattern
///
/// If not, the it is likely this should be replaced by ConvertValLogicalNameToDisplayName.
val ConvertValLogicalNameToDisplayNameCore: opName: string -> string
/// Take a core display name for a value (e.g. op_Addition or PropertyName) and convert it to display text
/// Foo --> Foo
@ -105,16 +131,20 @@ val internal ConvertNameToDisplayName: name: string -> string
/// op_DereferencePercent --> (!%)
/// A-B --> ``A-B``
/// |A|_| --> (|A|_|)
/// let --> ``let``
/// type --> ``type``
/// params --> ``params``
/// base --> base
/// or --> or
/// mod --> mod
val internal ConvertValNameToDisplayName: isBaseVal: bool -> name: string -> string
val internal ConvertValLogicalNameToDisplayName: isBaseVal: bool -> name: string -> string
/// Like ConvertNameToDisplayName but produces a tagged layout
val internal ConvertNameToDisplayLayout: nonOpLayout: (string -> Layout) -> name: string -> Layout
/// Like ConvertLogicalNameToDisplayName but produces a tagged layout
val internal ConvertLogicalNameToDisplayLayout: nonOpLayout: (string -> Layout) -> name: string -> Layout
/// Like ConvertValNameToDisplayName but produces a tagged layout
val internal ConvertValNameToDisplayLayout: isBaseVal: bool -> nonOpLayout: (string -> Layout) -> name: string -> Layout
/// Like ConvertValLogicalNameToDisplayName but produces a tagged layout
val internal ConvertValLogicalNameToDisplayLayout:
isBaseVal: bool -> nonOpLayout: (string -> Layout) -> name: string -> Layout
val internal opNameCons: string
@ -143,14 +173,14 @@ val internal IsValidPrefixOperatorUse: s: string -> bool
val internal IsValidPrefixOperatorDefinitionName: s: string -> bool
val IsPrefixOperator: s: string -> bool
val IsLogicalPrefixOperator: logicalName: string -> bool
val IsLogicalInfixOpName: logicalName: string -> bool
val IsLogicalTernaryOperator: logicalName: string -> bool
val IsPunctuation: s: string -> bool
val IsTernaryOperator: s: string -> bool
val IsMangledInfixOperator: string -> bool
val internal (|Control|Equality|Relational|Indexer|FixedTypes|Other|):
opName: string -> Choice<unit, unit, unit, unit, unit, unit>
@ -203,13 +233,13 @@ val internal ActivePatternInfoOfValName: nm: string -> m: range -> ActivePattern
exception internal InvalidMangledStaticArg of string
val internal demangleProvidedTypeName: typeLogicalName: string -> string * (string * string)[]
val internal DemangleProvidedTypeName: typeLogicalName: string -> string * (string * string)[]
/// Mangle the static parameters for a provided type or method
val internal mangleProvidedTypeName: typeLogicalName: string * nonDefaultArgs: (string * string)[] -> string
val internal MangleProvidedTypeName: typeLogicalName: string * nonDefaultArgs: (string * string)[] -> string
/// Mangle the static parameters for a provided type or method
val internal computeMangledNameWithoutDefaultArgValues:
val internal ComputeMangledNameWithoutDefaultArgValues:
nm: string * staticArgs: 'a[] * defaultArgValues: (string * string option)[] -> string
val internal outArgCompilerGeneratedName: string

Просмотреть файл

@ -1186,7 +1186,7 @@ let ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams: Tai
staticParams.PApply((fun ps -> ps |> Array.map (fun sp -> sp.Name, (if sp.IsOptional then Some (string sp.RawDefaultValue) else None ))), range=m)
let defaultArgValues = defaultArgValues.PUntaint(id, m)
PrettyNaming.computeMangledNameWithoutDefaultArgValues(nm, staticArgs, defaultArgValues)
PrettyNaming.ComputeMangledNameWithoutDefaultArgValues(nm, staticArgs, defaultArgValues)
/// Apply the given provided method to the given static arguments (the arguments are assumed to have been sorted into application order)
let TryApplyProvidedMethod(methBeforeArgs: Tainted<ProvidedMethodBase>, staticArgs: obj[], m: range) =
@ -1243,7 +1243,7 @@ let TryLinkProvidedType(resolver: Tainted<ITypeProvider>, moduleOrNamespace: str
// Demangle the static parameters
let typeName, argNamesAndValues =
try
PrettyNaming.demangleProvidedTypeName typeLogicalName
PrettyNaming.DemangleProvidedTypeName typeLogicalName
with PrettyNaming.InvalidMangledStaticArg piece ->
error(Error(FSComp.SR.etProvidedTypeReferenceInvalidText piece, range0))

Просмотреть файл

@ -686,7 +686,7 @@ type Entity =
#if !NO_TYPEPROVIDERS
member x.IsStaticInstantiationTycon =
x.IsProvidedErasedTycon &&
let _nm, args = demangleProvidedTypeName x.LogicalName
let _nm, args = DemangleProvidedTypeName x.LogicalName
args.Length > 0
#endif
@ -697,7 +697,7 @@ type Entity =
if x.IsModuleOrNamespace then x.DemangledModuleOrNamespaceName
#if !NO_TYPEPROVIDERS
elif x.IsProvidedErasedTycon then
let nm, args = demangleProvidedTypeName nm
let nm, args = DemangleProvidedTypeName nm
if withStaticParameters && args.Length > 0 then
nm + "<" + String.concat "," (Array.map snd args) + ">"
else
@ -710,7 +710,7 @@ type Entity =
| tps ->
let nm = DemangleGenericTypeName nm
let isArray = nm.StartsWithOrdinal("[") && nm.EndsWithOrdinal("]")
let nm = if coreName || isArray then nm else ConvertNameToDisplayName nm
let nm = if coreName || isArray then nm else ConvertLogicalNameToDisplayName nm
if withUnderscoreTypars then
let typarNames = tps |> List.map (fun _ -> "_")
nm + "<" + String.concat "," typarNames + ">"
@ -1680,18 +1680,18 @@ type UnionCase =
///
/// Backticks and parens are not added for non-identifiers.
///
/// Note logical names op_Nil and op_ConsCons become [] and :: respectively.
member uc.DisplayNameCore = uc.LogicalName |> DecompileOpName
/// Note logical names op_Nil and op_ColonColon become [] and :: respectively.
member uc.DisplayNameCore = uc.LogicalName |> ConvertValLogicalNameToDisplayNameCore
/// Get the display name of the union case
///
/// Backticks and parens are added for non-identifiers.
///
/// Note logical names op_Nil and op_ConsCons become ([]) and (::) respectively.
member uc.DisplayName = uc.LogicalName |> ConvertValNameToDisplayName false
/// Note logical names op_Nil and op_ColonColon become ([]) and (::) respectively.
member uc.DisplayName = uc.LogicalName |> ConvertValLogicalNameToDisplayName false
/// Get the name of the case in generated IL code.
/// Note logical names `op_Nil` and `op_ConsCons` become `Empty` and `Cons` respectively.
/// Note logical names `op_Nil` and `op_ColonColon` become `Empty` and `Cons` respectively.
/// This is because this is how ILX union code gen expects to see them.
member uc.CompiledName =
let idText = uc.Id.idText
@ -1803,7 +1803,7 @@ type RecdField =
member v.DisplayNameCore = v.LogicalName
/// Name of the field
member v.DisplayName = v.DisplayNameCore |> ConvertNameToDisplayName
member v.DisplayName = v.DisplayNameCore |> ConvertLogicalNameToDisplayName
/// Indicates a compiler generated field, not visible to Intellisense or name resolution
member v.IsCompilerGenerated = v.rfield_secret
@ -2977,7 +2977,7 @@ type Val =
///
/// Note: here "Core" means "without added backticks or parens"
member x.DisplayNameCore =
x.DisplayNameCoreMangled |> DecompileOpName
x.DisplayNameCoreMangled |> ConvertValLogicalNameToDisplayNameCore
/// The full text for the value to show in error messages and to use in code.
/// This includes backticks, parens etc.
@ -2990,7 +2990,7 @@ type Val =
/// - If this is a base value --> base
/// - If this is a value named ``base`` --> ``base``
member x.DisplayName =
ConvertValNameToDisplayName x.IsBaseVal x.DisplayNameCoreMangled
ConvertValLogicalNameToDisplayName x.IsBaseVal x.DisplayNameCoreMangled
member x.SetValRec b = x.val_flags <- x.val_flags.WithRecursiveValInfo b
@ -4014,7 +4014,7 @@ type RecdFieldRef =
member x.FieldName = let (RecdFieldRef(_, id)) = x in id
/// Get the name of the field, with backticks added for non-identifier names
member x.DisplayName = x.FieldName |> ConvertNameToDisplayName
member x.DisplayName = x.FieldName |> ConvertLogicalNameToDisplayName
/// Get the Entity for the type containing this union case
member x.Tycon = x.TyconRef.Deref
@ -4188,6 +4188,10 @@ type AnonRecdTypeInfo =
member x.IsLinked = (match x.SortedIds with null -> true | _ -> false)
member x.DisplayNameCoreByIdx idx = x.SortedNames[idx]
member x.DisplayNameByIdx idx = x.SortedNames[idx] |> ConvertLogicalNameToDisplayName
[<RequireQualifiedAccess>]
type TupInfo =
/// Some constant, e.g. true or false for tupInfo

Просмотреть файл

@ -1136,7 +1136,7 @@ type UnionCase =
override ToString: unit -> string
/// Get the name of the case in generated IL code.
/// Note logical names `op_Nil` type `op_ConsCons` become `Empty` type `Cons` respectively.
/// Note logical names `op_Nil` type `op_ColonColon` become `Empty` type `Cons` respectively.
/// This is because this is how ILX union code gen expects to see them.
member CompiledName: string
@ -1148,16 +1148,16 @@ type UnionCase =
/// Get the display name of the union case
///
/// Backticks type parens are added for non-identifiers.
/// Backticks are added for non-identifiers.
///
/// Note logical names op_Nil type op_ConsCons become ([]) type (::) respectively.
/// Note logical names op_Nil and op_ColonColon become ([]) and (::) respectively.
member DisplayName: string
/// Get the core of the display name of the union case
///
/// Backticks type parens are not added for non-identifiers.
/// Backticks and parens are not added for non-identifiers.
///
/// Note logical names op_Nil type op_ConsCons become [] type :: respectively.
/// Note logical names op_Nil type op_ColonColon become [] and :: respectively.
member DisplayNameCore: string
/// Indicates if the union case has no fields
@ -1940,7 +1940,12 @@ type Val =
member DisplayNameCore: string
/// The display name of the value or method but without operator names decompiled type without backticks etc.
/// This is very close to LogicalName except that properties have get_ removed.
///
/// This is very close to LogicalName except that properties have get_ removed and
/// interface implementation methods report the name of the implemented method.
///
/// Note: avoid using this, we would like to remove it. All uses should be code-reviewed and
/// gradually eliminated in favour of DisplayName, DisplayNameCore or LogicalName.
///
/// Note: here "Core" means "without added backticks or parens"
/// Note: here "Mangled" means "op_Addition"
@ -2653,10 +2658,39 @@ type ValRef =
/// Dereference the ValRef to a Val.
member Deref: Val
/// The full text for the value to show in error messages type to use in code.
/// This includes backticks, parens etc.
///
/// - If this is a property --> Foo
/// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot
/// - If this is an active pattern --> (|A|_|)
/// - If this is an operator --> (+)
/// - If this is an identifier needing backticks --> ``A-B``
/// - If this is a base value --> base
/// - If this is a value named ``base`` --> ``base``
member DisplayName: string
/// The display name of the value or method with operator names decompiled but without backticks etc.
///
/// Note: here "Core" means "without added backticks or parens"
member DisplayNameCore: string
/// The display name of the value or method but without operator names decompiled type without backticks etc.
///
/// This is very close to LogicalName except that properties have get_ removed and
/// interface implementation methods report the name of the implemented method.
///
/// Note: avoid using this, we would like to remove it. All uses should be code-reviewed and
/// gradually eliminated in favour of DisplayName, DisplayNameCore or LogicalName.
///
/// Note: here "Core" means "without added backticks or parens"
/// Note: here "Mangled" means "op_Addition"
///
/// - If this is a property --> Foo
/// - If this is an implementation of an abstract slot then this is the name of the method implemented by the abstract slot
/// - If this is an active pattern --> |A|_|
/// - If this is an operator --> op_Addition
/// - If this is an identifier needing backticks --> A-B
member DisplayNameCoreMangled: string
/// Get the type of the value including any generic type parameters
@ -2666,7 +2700,7 @@ type ValRef =
member Id: Syntax.Ident
/// Gets the dispatch slots implemented by this method
/// Gets the dispatch slots implemented by this method, either 0 or 1
member ImplementedSlotSigs: SlotSig list
/// Get the inline declaration on a parameter or other non-function-declaration value, used for optimization
@ -2979,6 +3013,12 @@ type AnonRecdTypeInfo =
member IsLinked: bool
/// Get the display name for one of the fields of the anonymous record, by index
member DisplayNameByIdx: idx: int -> string
/// Get the core of the display name for one of the fields of the anonymous record, by index
member DisplayNameCoreByIdx: idx: int -> string
[<RequireQualifiedAccess>]
type TupInfo =

Просмотреть файл

@ -3967,7 +3967,7 @@ module DebugPrint =
leftL (tagText "<") ^^ intL tpNames.Length ^^ sepL (tagText ">[") ^^ commaListL (List.map intL ns) ^^ rightL (tagText "]")
let valL (v: Val) =
let vsL = wordL (tagText (DecompileOpName v.LogicalName)) |> stampL v.Stamp
let vsL = wordL (tagText (ConvertValLogicalNameToDisplayNameCore v.LogicalName)) |> stampL v.Stamp
let vsL = vsL -- layoutAttribs v.Attribs
vsL
@ -9015,7 +9015,7 @@ let TryGetActivePatternInfo (vref: ValRef) =
ActivePatternInfoOfValName vref.DisplayNameCoreMangled vref.Range
type ActivePatternElemRef with
member x.Name =
member x.LogicalName =
let (APElemRef(_, vref, n, _)) = x
match TryGetActivePatternInfo vref with
| None -> error(InternalError("not an active pattern name", vref.Range))
@ -9024,6 +9024,10 @@ type ActivePatternElemRef with
if n < 0 || n >= List.length nms then error(InternalError("name_of_apref: index out of range for active pattern reference", vref.Range))
List.item n nms
member x.DisplayNameCore = x.LogicalName
member x.DisplayName = x.LogicalName |> ConvertLogicalNameToDisplayName
let mkChoiceTyconRef (g: TcGlobals) m n =
match n with
| 0 | 1 -> error(InternalError("mkChoiceTyconRef", m))
@ -9045,7 +9049,10 @@ let mkChoiceCaseRef g m n i =
mkUnionCaseRef (mkChoiceTyconRef g m n) ("Choice"+string (i+1)+"Of"+string n)
type ActivePatternInfo with
member x.Names = x.ActiveTags
member x.DisplayNameCoreByIdx idx = x.ActiveTags[idx]
member x.DisplayNameByIdx idx = x.ActiveTags[idx] |> ConvertLogicalNameToDisplayName
member apinfo.ResultType g m retTys isStruct =
let choicety = mkChoiceTy g m retTys

Просмотреть файл

@ -2395,7 +2395,11 @@ val mkFastForLoop: TcGlobals -> DebugPointAtFor * DebugPointAtInOrTo * range * V
type ActivePatternElemRef with
member Name: string
member LogicalName: string
member DisplayNameCore: string
member DisplayName: string
val TryGetActivePatternInfo: ValRef -> PrettyNaming.ActivePatternInfo option
@ -2403,10 +2407,16 @@ val mkChoiceCaseRef: g: TcGlobals -> m: range -> n: int -> i: int -> UnionCaseRe
type PrettyNaming.ActivePatternInfo with
member Names: string list
/// Get the core of the display name for one of the cases of the active pattern, by index
member DisplayNameCoreByIdx: idx: int -> string
/// Get the display name for one of the cases of the active pattern, by index
member DisplayNameByIdx: idx: int -> string
/// Get the result type for the active pattern
member ResultType: g: TcGlobals -> range -> TType list -> bool -> TType
/// Get the overall type for a function that implements the active pattern
member OverallType: g: TcGlobals -> m: range -> argTy: TType -> retTys: TType list -> isStruct: bool -> TType
val doesActivePatternHaveFreeTypars: TcGlobals -> ValRef -> bool

Просмотреть файл

@ -16,7 +16,7 @@ type CompletionTests() =
let lines = [ "let x = 1"
"x." ]
let! completions = script.GetCompletionItems(String.Join("\n", lines), 2, 2)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "CompareTo")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "CompareTo")
Assert.Equal(1, matchingCompletions.Length)
} |> Async.StartAsTask :> Task
@ -26,7 +26,7 @@ type CompletionTests() =
use script = new FSharpScript()
script.Eval("let x = 1") |> ignoreValue
let! completions = script.GetCompletionItems("x.", 1, 2)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "CompareTo")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "CompareTo")
Assert.Equal(1, matchingCompletions.Length)
} |> Async.StartAsTask :> Task
@ -37,7 +37,7 @@ type CompletionTests() =
script.Eval("open System") |> ignoreValue
script.Eval("let t = TimeSpan.FromHours(1.0)") |> ignoreValue
let! completions = script.GetCompletionItems("t.", 1, 2)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "TotalHours")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "TotalHours")
Assert.Equal(1, matchingCompletions.Length)
} |> Async.StartAsTask :> Task
@ -46,7 +46,7 @@ type CompletionTests() =
async {
use script = new FSharpScript()
let! completions = script.GetCompletionItems("System.String.", 1, 14)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Join")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "Join")
Assert.True(matchingCompletions.Length >= 1)
} |> Async.StartAsTask :> Task
@ -55,7 +55,7 @@ type CompletionTests() =
async {
use script = new FSharpScript()
let! completions = script.GetCompletionItems("System.", 1, 7)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "String")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "String")
Assert.True(matchingCompletions.Length >= 1)
} |> Async.StartAsTask :> Task
@ -64,7 +64,7 @@ type CompletionTests() =
async {
use script = new FSharpScript()
let! completions = script.GetCompletionItems("System.", 1, 7)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Collections")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "Collections")
Assert.Equal(1, matchingCompletions.Length)
} |> Async.StartAsTask :> Task
@ -76,7 +76,7 @@ type CompletionTests() =
"let list = new System.Collections.Generic.List<int>()"
"list." ]
let! completions = script.GetCompletionItems(String.Join("\n", lines), 3, 5)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Select")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "Select")
Assert.Equal(1, matchingCompletions.Length)
} |> Async.StartAsTask :> Task
@ -91,30 +91,30 @@ type CompletionTests() =
" static member ``|A|_|``(a:C, b:C) = C()"
"C." ]
let completions = script.GetCompletionItems(String.Join("\n", lines), 7, 2) |> Async.RunSynchronously
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Long Name")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "Long Name")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("``Long Name``", matchingCompletions.[0].NameInCode)
// Things with names like op_Addition are suppressed from completion by FCS
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "+")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "+")
Assert.Equal(0, matchingCompletions.Length)
// Strange names like ``+`` and ``-`` are just normal text and not operators
// and are present in competion lists
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "-")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "-")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("``-``", matchingCompletions.[0].NameInCode)
// ``base`` is a strange name but is still present. In this case the inserted
// text NameInCode is ``base`` because the thing is not a base value mapping to
// the base keyword
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "base")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "base")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("``base``", matchingCompletions.[0].NameInCode)
// ``|A|_|`` is a strange name like the name of an active pattern but is still present.
// In this case the inserted is (|A|_|)
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "|A|_|")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "|A|_|")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("(|A|_|)", matchingCompletions.[0].NameInCode)
@ -130,30 +130,30 @@ type CompletionTests() =
" let (|A|_|)(a:int, b:int) = None"
"M." ]
let completions = script.GetCompletionItems(String.Join("\n", lines), 7, 2) |> Async.RunSynchronously
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "Long Name")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "Long Name")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("``Long Name``", matchingCompletions.[0].NameInCode)
// Things with names like op_Addition are suppressed from completion by FCS
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "+")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "+")
Assert.Equal(0, matchingCompletions.Length)
// Strange names like ``+`` and ``-`` are just normal text and not operators
// and are present in competion lists
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "-")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "-")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("``-``", matchingCompletions.[0].NameInCode)
// ``base`` is a strange name but is still present. In this case the inserted
// text NameInCode is ``base`` because the thing is not a base value mapping to
// the base keyword
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "base")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "base")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("``base``", matchingCompletions.[0].NameInCode)
// (|A|_|) is an active pattern and the completion item is the
// active pattern case A. In this case the inserted is A
let matchingCompletions = completions |> Array.filter (fun d -> d.Name = "A")
let matchingCompletions = completions |> Array.filter (fun d -> d.NameInList = "A")
Assert.Equal(1, matchingCompletions.Length)
Assert.Equal("A", matchingCompletions.[0].NameInCode)

Просмотреть файл

@ -2596,9 +2596,11 @@ FSharp.Compiler.EditorServices.DeclarationListItem: Microsoft.FSharp.Core.FSharp
FSharp.Compiler.EditorServices.DeclarationListItem: System.String FullName
FSharp.Compiler.EditorServices.DeclarationListItem: System.String Name
FSharp.Compiler.EditorServices.DeclarationListItem: System.String NameInCode
FSharp.Compiler.EditorServices.DeclarationListItem: System.String NameInList
FSharp.Compiler.EditorServices.DeclarationListItem: System.String get_FullName()
FSharp.Compiler.EditorServices.DeclarationListItem: System.String get_Name()
FSharp.Compiler.EditorServices.DeclarationListItem: System.String get_NameInCode()
FSharp.Compiler.EditorServices.DeclarationListItem: System.String get_NameInList()
FSharp.Compiler.EditorServices.EntityCache
FSharp.Compiler.EditorServices.EntityCache: T Locking[T](Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.EditorServices.IAssemblyContentCache,T])
FSharp.Compiler.EditorServices.EntityCache: Void .ctor()
@ -3154,9 +3156,9 @@ FSharp.Compiler.EditorServices.NavigableContainer: Int32 CompareTo(System.Object
FSharp.Compiler.EditorServices.NavigableContainer: Int32 CompareTo(System.Object, System.Collections.IComparer)
FSharp.Compiler.EditorServices.NavigableContainer: Int32 GetHashCode()
FSharp.Compiler.EditorServices.NavigableContainer: Int32 GetHashCode(System.Collections.IEqualityComparer)
FSharp.Compiler.EditorServices.NavigableContainer: System.String Name
FSharp.Compiler.EditorServices.NavigableContainer: System.String LogicalName
FSharp.Compiler.EditorServices.NavigableContainer: System.String ToString()
FSharp.Compiler.EditorServices.NavigableContainer: System.String get_Name()
FSharp.Compiler.EditorServices.NavigableContainer: System.String get_LogicalName()
FSharp.Compiler.EditorServices.NavigableContainer: Void .ctor(FSharp.Compiler.EditorServices.NavigableContainerType, System.String)
FSharp.Compiler.EditorServices.NavigableContainerType
FSharp.Compiler.EditorServices.NavigableContainerType+Tags: Int32 Exception
@ -3210,9 +3212,9 @@ FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.Text.Range Range
FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.Text.Range get_Range()
FSharp.Compiler.EditorServices.NavigableItem: Int32 GetHashCode()
FSharp.Compiler.EditorServices.NavigableItem: Int32 GetHashCode(System.Collections.IEqualityComparer)
FSharp.Compiler.EditorServices.NavigableItem: System.String Name
FSharp.Compiler.EditorServices.NavigableItem: System.String LogicalName
FSharp.Compiler.EditorServices.NavigableItem: System.String ToString()
FSharp.Compiler.EditorServices.NavigableItem: System.String get_Name()
FSharp.Compiler.EditorServices.NavigableItem: System.String get_LogicalName()
FSharp.Compiler.EditorServices.NavigableItem: Void .ctor(System.String, FSharp.Compiler.Text.Range, Boolean, FSharp.Compiler.EditorServices.NavigableItemKind, FSharp.Compiler.EditorServices.NavigableContainer)
FSharp.Compiler.EditorServices.NavigableItemKind
FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Constructor
@ -3356,9 +3358,9 @@ FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.Text.Range get_Bo
FSharp.Compiler.EditorServices.NavigationItem: FSharp.Compiler.Text.Range get_Range()
FSharp.Compiler.EditorServices.NavigationItem: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] Access
FSharp.Compiler.EditorServices.NavigationItem: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynAccess] get_Access()
FSharp.Compiler.EditorServices.NavigationItem: System.String Name
FSharp.Compiler.EditorServices.NavigationItem: System.String LogicalName
FSharp.Compiler.EditorServices.NavigationItem: System.String UniqueName
FSharp.Compiler.EditorServices.NavigationItem: System.String get_Name()
FSharp.Compiler.EditorServices.NavigationItem: System.String get_LogicalName()
FSharp.Compiler.EditorServices.NavigationItem: System.String get_UniqueName()
FSharp.Compiler.EditorServices.NavigationItemKind
FSharp.Compiler.EditorServices.NavigationItemKind+Tags: Int32 Exception
@ -5684,24 +5686,22 @@ FSharp.Compiler.Syntax.ParserDetail: Int32 Tag
FSharp.Compiler.Syntax.ParserDetail: Int32 get_Tag()
FSharp.Compiler.Syntax.ParserDetail: System.String ToString()
FSharp.Compiler.Syntax.PrettyNaming
FSharp.Compiler.Syntax.PrettyNaming: Boolean DoesIdentifierNeedBackticks(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsActivePatternName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsCompilerGeneratedName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsIdentifierFirstCharacter(Char)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsIdentifierName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsIdentifierPartCharacter(Char)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsLogicalInfixOpName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsLogicalOpName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsLogicalPrefixOperator(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsLogicalTernaryOperator(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsLongIdentifierPartCharacter(Char)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsMangledInfixOperator(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsMangledOpName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsOperatorDisplayName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsPrefixOperator(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsPunctuation(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Boolean IsTernaryOperator(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Microsoft.FSharp.Collections.FSharpList`1[System.String] GetLongNameFromString(System.String)
FSharp.Compiler.Syntax.PrettyNaming: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryChopPropertyName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: System.String AddBackticksToIdentifierIfNeeded(System.String)
FSharp.Compiler.Syntax.PrettyNaming: System.String CompileOpName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: System.String DecompileOpName(System.String)
FSharp.Compiler.Syntax.PrettyNaming: System.String ConvertValLogicalNameToDisplayNameCore(System.String)
FSharp.Compiler.Syntax.PrettyNaming: System.String FormatAndOtherOverloadsString(Int32)
FSharp.Compiler.Syntax.PrettyNaming: System.String FsiDynamicModulePrefix
FSharp.Compiler.Syntax.PrettyNaming: System.String NormalizeIdentifierBackticks(System.String)
@ -9829,12 +9829,10 @@ FSharp.Compiler.Text.TextTag: Int32 Tag
FSharp.Compiler.Text.TextTag: Int32 get_Tag()
FSharp.Compiler.Text.TextTag: System.String ToString()
FSharp.Compiler.Tokenization.FSharpKeywords
FSharp.Compiler.Tokenization.FSharpKeywords: Boolean DoesIdentifierNeedBackticks(System.String)
FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.String] KeywordNames
FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.String] get_KeywordNames()
FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,System.String]] KeywordsWithDescription
FSharp.Compiler.Tokenization.FSharpKeywords: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,System.String]] get_KeywordsWithDescription()
FSharp.Compiler.Tokenization.FSharpKeywords: System.String AddBackticksToIdentifierIfNeeded(System.String)
FSharp.Compiler.Tokenization.FSharpKeywords: System.String NormalizeIdentifierBackticks(System.String)
FSharp.Compiler.Tokenization.FSharpLexer
FSharp.Compiler.Tokenization.FSharpLexer: Void Tokenize(FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpFunc`2[FSharp.Compiler.Tokenization.FSharpToken,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Tokenization.FSharpLexerFlags], Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpMap`2[System.String,System.String]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken])

Просмотреть файл

@ -13,30 +13,30 @@ type ManglingNamesOfProvidedTypesWithSingleParameter() =
[<Fact>]
member this.MangleWithNonDefaultValue() =
let mangled =
PrettyNaming.computeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "abc" |])
PrettyNaming.ComputeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "abc" |])
Assert.shouldBe "MyNamespace.Test,Foo=\"xyz\"" mangled
[<Fact>]
member this.MangleWithDefaultValue() =
let mangled =
PrettyNaming.computeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "xyz" |])
PrettyNaming.ComputeMangledNameWithoutDefaultArgValues("MyNamespace.Test", [| "xyz" |], [| "Foo", Some "xyz" |])
Assert.shouldBe "MyNamespace.Test" mangled
[<Fact>]
member this.DemangleNonDefaultValue() =
let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test,Foo=\"xyz\""
let name, parameters = PrettyNaming.DemangleProvidedTypeName "MyNamespace.Test,Foo=\"xyz\""
Assert.shouldBe "MyNamespace.Test" name
Assert.shouldBeEquivalentTo [| "Foo", "xyz" |] parameters
[<Fact>]
member this.DemangleDefaultValue() =
let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test,"
let name, parameters = PrettyNaming.DemangleProvidedTypeName "MyNamespace.Test,"
Assert.shouldBe "MyNamespace.Test" name
Assert.shouldBeEquivalentTo [||] parameters
[<Fact>]
member this.DemangleNewDefaultValue() =
let name, parameters = PrettyNaming.demangleProvidedTypeName "MyNamespace.Test"
let name, parameters = PrettyNaming.DemangleProvidedTypeName "MyNamespace.Test"
Assert.shouldBe "MyNamespace.Test" name
Assert.shouldBeEquivalentTo [||] parameters
@ -46,7 +46,7 @@ type ManglingNamesOfProvidedTypesWithMultipleParameter() =
[<Fact>]
member this.MangleWithNonDefaultValue() =
let mangled =
PrettyNaming.computeMangledNameWithoutDefaultArgValues
PrettyNaming.ComputeMangledNameWithoutDefaultArgValues
("MyNamespace.Test", [| "xyz"; "abc" |],
[| "Foo", Some "foo"
"Foo2", Some "foo2" |])
@ -55,7 +55,7 @@ type ManglingNamesOfProvidedTypesWithMultipleParameter() =
[<Fact>]
member this.MangleWithDefaultValue() =
let mangled =
PrettyNaming.computeMangledNameWithoutDefaultArgValues
PrettyNaming.ComputeMangledNameWithoutDefaultArgValues
("MyNamespace.Test", [| "xyz"; "abc" |],
[| "Foo", Some "xyz"
"Foo2", Some "abc" |])
@ -63,7 +63,7 @@ type ManglingNamesOfProvidedTypesWithMultipleParameter() =
[<Fact>]
member this.DemangleMultiParameter() =
let name, parameters = PrettyNaming.demangleProvidedTypeName "TestType,Foo=\"xyz\",Foo2=\"abc\""
let name, parameters = PrettyNaming.DemangleProvidedTypeName "TestType,Foo=\"xyz\",Foo2=\"abc\""
Assert.shouldBe "TestType" name
Assert.shouldBe([| "Foo", "xyz"
"Foo2", "abc" |], parameters)

Просмотреть файл

@ -89,7 +89,7 @@ let ``Intro test`` () =
// Get declarations (autocomplete) for a location
let partialName = { QualifyingIdents = []; PartialIdent = "msg"; EndColumn = 22; LastDotPos = None }
let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 7, inputLines[6], partialName, (fun _ -> []))
CollectionAssert.AreEquivalent(stringMethods,[ for item in decls.Items -> item.Name ])
CollectionAssert.AreEquivalent(stringMethods,[ for item in decls.Items -> item.NameInList ])
// Get overloads of the String.Concat method
let methods = typeCheckResults.GetMethods(5, 27, inputLines[4], Some ["String"; "Concat"])
@ -280,7 +280,7 @@ let ``Expression typing test`` () =
//
for col in 42..43 do
let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 2, inputLines[1], PartialLongName.Empty(col), (fun _ -> []))
let autoCompleteSet = set [ for item in decls.Items -> item.Name ]
let autoCompleteSet = set [ for item in decls.Items -> item.NameInList ]
autoCompleteSet |> shouldEqual (set stringMethods)
// The underlying problem is that the parser error recovery doesn't include _any_ information for
@ -301,8 +301,8 @@ type Test() =
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines[3], PartialLongName.Empty(20), (fun _ -> []))
let item = decls.Items |> Array.tryFind (fun d -> d.Name = "abc")
decls.Items |> Seq.exists (fun d -> d.Name = "abc") |> shouldEqual true
let item = decls.Items |> Array.tryFind (fun d -> d.NameInList = "abc")
decls.Items |> Seq.exists (fun d -> d.NameInList = "abc") |> shouldEqual true
[<Test>]
let ``Find function from member 2`` () =
@ -318,8 +318,8 @@ type Test() =
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines[3], PartialLongName.Empty(21), (fun _ -> []))
let item = decls.Items |> Array.tryFind (fun d -> d.Name = "abc")
decls.Items |> Seq.exists (fun d -> d.Name = "abc") |> shouldEqual true
let item = decls.Items |> Array.tryFind (fun d -> d.NameInList = "abc")
decls.Items |> Seq.exists (fun d -> d.NameInList = "abc") |> shouldEqual true
[<Test>]
let ``Find function from var`` () =
@ -335,7 +335,7 @@ type Test() =
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 4, inputLines[3], PartialLongName.Empty(14), (fun _ -> []))
decls.Items |> Seq.exists (fun d -> d.Name = "abc") |> shouldEqual true
decls.Items |> Seq.exists (fun d -> d.NameInList = "abc") |> shouldEqual true
[<Test>]
@ -355,7 +355,7 @@ type B(bar) =
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 7, inputLines[6], PartialLongName.Empty(17), (fun _ -> []))
decls.Items |> Seq.exists (fun d -> d.Name = "bar") |> shouldEqual true
decls.Items |> Seq.exists (fun d -> d.NameInList = "bar") |> shouldEqual true
@ -378,7 +378,7 @@ type B(bar) =
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
let decls = typeCheckResults.GetDeclarationListInfo(Some parseResult, 9, inputLines[8], PartialLongName.Empty(7), (fun _ -> []))
decls.Items |> Seq.exists (fun d -> d.Name = "bar") |> shouldEqual true
decls.Items |> Seq.exists (fun d -> d.NameInList = "bar") |> shouldEqual true
[<Test; Ignore("SKIPPED: see #139")>]

Просмотреть файл

@ -4,42 +4,66 @@ open FSharp.Compiler.Syntax.PrettyNaming
open FsUnit
open NUnit.Framework
[<Test>]
let ``words in operator name should not be considered as mangled infix operator`` () =
IsMangledInfixOperator "$foo hoo"
|> should equal false
// invalid operator name
[<TestCase ("op_Dollarfoo", false)>]
// random stuff
[<TestCase ("foo", false)>]
// operator display representations
[<TestCase ("~%%", false)>]
[<TestCase ("~%", false)>]
// not infix operators
[<TestCase ("op_BitwiseOr", false)>]
[<TestCase ("op_Equality", false)>]
// valid logical names
[<TestCase ("op_Splice", true)>]
[<TestCase ("op_SpliceUntyped", true)>]
let ``IsLogicalPrefixOperator`` logicalName result =
IsLogicalPrefixOperator logicalName
|> should equal result
IsMangledInfixOperator "@foo hoo"
|> should equal false
// empty string
[<TestCase ("", false)>]
// invalid opearators
[<TestCase ("op_Dynamic", false)>]
[<TestCase ("op_RangeStep", false)>]
// display representation
[<TestCase ("?<-", false)>]
// correct option
[<TestCase ("op_DynamicAssignment", true)>]
let ``IsLogicalTernaryOperator`` logicalName result =
IsLogicalTernaryOperator logicalName
|> should equal result
[<Test>]
let ``typo in mangled operator name should not be considered as mangled infix operator`` () =
IsMangledInfixOperator "op_Nagation"
|> should equal false
[<Test>]
let ``valid mangled operator name should be considered as mangled infix operator`` () =
IsMangledInfixOperator "op_Addition"
|> should equal true
IsMangledInfixOperator "op_Append"
|> should equal true
[<Test>]
let ``invalid mangled operator name should not be considered as mangled infix operator`` () =
IsMangledInfixOperator "op_Dollarfoo"
|> should equal false
IsMangledInfixOperator "foo"
|> should equal false
[<Test>]
let ``symbols in mangled operator name should not be considered as mangled infix operator`` () =
IsMangledInfixOperator "$foo"
|> should equal false
IsMangledInfixOperator "$"
|> should equal false
IsMangledInfixOperator "+"
|> should equal false
// words in operator name
[<TestCase ("$foo hoo", false)>]
[<TestCase ("@foo hoo", false)>]
// typo in operator name
[<TestCase ("op_Nagation", false)>]
// invalid operator name
[<TestCase ("op_Dollarfoo", false)>]
[<TestCase ("foo", false)>]
[<TestCase ("$foo", false)>]
// random symbols
[<TestCase ("$", false)>]
// operator display representations
[<TestCase ("+", false)>]
[<TestCase ("[]", false)>]
[<TestCase ("::", false)>]
[<TestCase ("~++", false)>]
[<TestCase (".. ..", false)>]
// not infix operators
[<TestCase ("op_Splice", false)>]
[<TestCase ("op_SpliceUntyped", false)>]
// valid logical names
[<TestCase ("op_Addition", true)>]
[<TestCase ("op_Append", true)>]
[<TestCase ("op_ColonColon", true)>]
[<TestCase ("op_BitwiseOr", true)>]
[<TestCase ("op_GreaterThanOrEqual", true)>]
[<TestCase ("op_Dynamic", true)>]
[<TestCase ("op_ArrayLookup", true)>]
[<TestCase ("op_DynamicAssignment", true)>]
[<TestCase ("op_ArrayAssign", true)>]
let ``IsLogicalInfixOpName`` logicalName result =
IsLogicalInfixOpName logicalName
|> should equal result

Просмотреть файл

@ -4013,7 +4013,7 @@ let ``Test project28 all symbols in signature`` () =
("FSharpEntity", "Use", "T:M.Use");
("FSharpMemberOrFunctionOrValue", "``.ctor``", "M:M.Use.#ctor");
("FSharpMemberOrFunctionOrValue", "Test", "M:M.Use.Test``1(``0)");
("FSharpGenericParameter", "?", "")|]
("FSharpGenericParameter", "``?``", "")|]
|> Array.iter (fun x ->
if xmlDocSigs |> Array.exists (fun y -> x = y) |> not then
failwithf "%A does not exist in the collection." x

Просмотреть файл

@ -36,7 +36,7 @@ type internal FSharpRenameParamToMatchSignature
let diagnostics = ImmutableArray.Create diagnostic
let suggestion = parts.Groups.[1].Value
let replacement = AddBackticksToIdentifierIfNeeded suggestion
let replacement = NormalizeIdentifierBackticks suggestion
let computeChanges() =
asyncMaybe {
let document = context.Document

Просмотреть файл

@ -46,7 +46,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider
let declInfo = checkFileResults.GetDeclarationListInfo(Some parseFileResults, fcsCaretLineNumber, lineText, partialName)
let addNames (addToBuffer:string -> unit) =
for item in declInfo.Items do
addToBuffer item.Name
addToBuffer item.NameInList
let diagnostics =
context.Diagnostics
@ -54,7 +54,7 @@ type internal FSharpReplaceWithSuggestionCodeFixProvider
|> Seq.toImmutableArray
for suggestion in CompilerDiagnostics.GetSuggestedNames addNames unresolvedIdentifierText do
let replacement = PrettyNaming.AddBackticksToIdentifierIfNeeded suggestion
let replacement = PrettyNaming.NormalizeIdentifierBackticks suggestion
let codeFix =
CodeFixHelpers.createTextChangeCodeFix(
CompilerDiagnostics.GetErrorMessage (FSharpDiagnosticKind.ReplaceWithSuggestion suggestion),

Просмотреть файл

@ -128,7 +128,7 @@ type internal FSharpCompletionProvider
if n <> 0 then n else
n <- (not x.IsOwnMember).CompareTo(not y.IsOwnMember)
if n <> 0 then n else
n <- String.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase)
n <- String.Compare(x.NameInList, y.NameInList, StringComparison.OrdinalIgnoreCase)
if n <> 0 then n else
x.MinorPriority.CompareTo(y.MinorPriority))
@ -142,7 +142,7 @@ type internal FSharpCompletionProvider
| _ -> null // Icky, but this is how roslyn handles it
let filterText =
match declarationItem.NamespaceToOpen, declarationItem.Name.Split '.' with
match declarationItem.NamespaceToOpen, declarationItem.NameInList.Split '.' with
// There is no namespace to open and the item name does not contain dots, so we don't need to pass special FilterText to Roslyn.
| None, [|_|] -> null
// Either we have a namespace to open ("DateTime (open System)") or item name contains dots ("Array.map"), or both.
@ -151,7 +151,7 @@ type internal FSharpCompletionProvider
let completionItem =
FSharpCommonCompletionItem.Create(
declarationItem.Name,
declarationItem.NameInList,
null,
rules = noCommitOnSpaceRules,
glyph = Nullable glyph,
@ -166,7 +166,7 @@ type internal FSharpCompletionProvider
| _ -> completionItem
let completionItem =
if declarationItem.Name <> declarationItem.NameInCode then
if declarationItem.NameInList <> declarationItem.NameInCode then
completionItem.AddProperty(NameInCodePropName, declarationItem.NameInCode)
else completionItem

Просмотреть файл

@ -363,10 +363,11 @@ type internal FSharpSignatureHelpProvider
taggedText |> Seq.iter (RoslynHelpers.CollectTaggedText tt)
let name =
if String.IsNullOrWhiteSpace(argument.DisplayName) then
let displayName = argument.DisplayName
if String.IsNullOrWhiteSpace displayName then
"arg" + string index
else
argument.DisplayName
displayName
let display =
[|

Просмотреть файл

@ -21,15 +21,16 @@ open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.EditorServices
open FSharp.Compiler.Syntax
type internal NavigableItem(document: Document, sourceSpan: TextSpan, glyph: Glyph, name: string, kind: string, additionalInfo: string) =
inherit FSharpNavigableItem(glyph, ImmutableArray.Create (TaggedText(TextTags.Text, name)), document, sourceSpan)
type internal NavigableItem(document: Document, sourceSpan: TextSpan, glyph: Glyph, logicalName: string, kind: string, additionalInfo: string) =
inherit FSharpNavigableItem(glyph, ImmutableArray.Create (TaggedText(TextTags.Text, logicalName)), document, sourceSpan)
member _.Name = name
// This use of compiler logical names is leaking out into the IDE. We should only report display names here.
member _.LogicalName = logicalName
member _.Kind = kind
member _.AdditionalInfo = additionalInfo
type internal NavigateToSearchResult(item: NavigableItem, matchKind: FSharpNavigateToMatchKind) =
inherit FSharpNavigateToSearchResult(item.AdditionalInfo, item.Kind, matchKind, item.Name, item)
inherit FSharpNavigateToSearchResult(item.AdditionalInfo, item.Kind, matchKind, item.LogicalName, item)
module private Index =
[<System.Diagnostics.DebuggerDisplay("{DebugString()}")>]
@ -69,10 +70,12 @@ module private Index =
for item in items do
let name =
if PrettyNaming.IsMangledOpName item.Name then
PrettyNaming.DecompileOpName item.Name
// This conversion back from logical names to display names should never be needed, because
// the FCS API should only report display names in the first place.
if PrettyNaming.IsLogicalOpName item.LogicalName then
PrettyNaming.ConvertValLogicalNameToDisplayNameCore item.LogicalName
else
item.Name
item.LogicalName
for i = 0 to name.Length - 1 do
entries.Add(IndexEntry(name, i, item))
@ -153,8 +156,8 @@ module private Utils =
let name =
match container.Type with
| NavigableContainerType.File ->
(Path.GetFileNameWithoutExtension project.Name) + ", " + (Path.GetFileName container.Name)
| _ -> container.Name
(Path.GetFileNameWithoutExtension project.Name) + ", " + (Path.GetFileName container.LogicalName)
| _ -> container.LogicalName
let combined = typeAsString + name
@ -197,10 +200,10 @@ type internal FSharpNavigateToSearchService
let additionalInfo = containerToString item.Container document
let _name =
if isSignatureFile document.FilePath then
item.Name + " (signature)"
item.LogicalName + " (signature)"
else
item.Name
yield NavigableItem(document, sourceSpan, glyph, item.Name, kind, additionalInfo)
item.LogicalName
yield NavigableItem(document, sourceSpan, glyph, item.LogicalName, kind, additionalInfo)
|]
return navigableItems
}
@ -251,7 +254,7 @@ type internal FSharpNavigateToSearchService
yield! items
|> Array.collect (fun item -> item.AllItems)
|> Array.Parallel.collect (fun x ->
patternMatcher.GetMatches(x.Name)
patternMatcher.GetMatches(x.LogicalName)
|> Seq.map (fun pm ->
NavigateToSearchResult(x, patternMatchKindToNavigateToMatchKind pm.Kind) :> FSharpNavigateToSearchResult)
|> Seq.toArray) |]

Просмотреть файл

@ -38,9 +38,9 @@ type internal FSharpNavigationBarItemService
|> Array.choose (fun decl ->
rangeToTextSpan(decl.Range)
|> Option.map(fun textSpan ->
NavigationBarSymbolItem(decl.Name, decl.RoslynGlyph, [| textSpan |], null) :> FSharpNavigationBarItem))
NavigationBarSymbolItem(decl.LogicalName, decl.RoslynGlyph, [| textSpan |], null) :> FSharpNavigationBarItem))
NavigationBarSymbolItem(topLevelDecl.Declaration.Name, topLevelDecl.Declaration.RoslynGlyph, [| topLevelTextSpan |], childItems)
NavigationBarSymbolItem(topLevelDecl.Declaration.LogicalName, topLevelDecl.Declaration.RoslynGlyph, [| topLevelTextSpan |], childItems)
:> FSharpNavigationBarItem)) :> IList<_>
}
|> Async.map (Option.defaultValue emptyResult)

Просмотреть файл

@ -127,7 +127,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
inherit Declarations_DEPRECATED()
// Sort the declarations, NOTE: we used ORDINAL comparison here, this is "by design" from F# 2.0, partly because it puts lowercase last.
let declarations = declarations |> Array.sortWith (fun d1 d2 -> compare d1.Name d2.Name)
let declarations = declarations |> Array.sortWith (fun d1 d2 -> compare d1.NameInList d2.NameInList)
let mutable lastBestMatch = ""
let isEmpty = (declarations.Length = 0)
@ -146,7 +146,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
let filterTextPrefix = filterText.[0..i]
match tab.TryGetValue filterTextPrefix with
| true, decls -> yield decls
| false, _ -> yield declarations |> Array.filter (fun s -> matcher.MatchSingleWordPattern(s.Name, filterTextPrefix)<>null)
| false, _ -> yield declarations |> Array.filter (fun s -> matcher.MatchSingleWordPattern(s.NameInList, filterTextPrefix)<>null)
yield declarations }
|> Seq.tryFind (fun arr -> arr.Length > 0)
|> (function None -> declarations | Some s -> s)
@ -160,7 +160,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
override decl.GetDisplayText(filterText, index) =
let decls = trimmedDeclarations filterText
if (index >= 0 && index < decls.Length) then
decls.[index].Name
decls.[index].NameInList
else ""
override decl.IsEmpty() = isEmpty
@ -172,7 +172,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
if (item.Glyph = FSharpGlyph.Error) then
""
else
item.Name
item.NameInList
else String.Empty
override decl.GetNameInCode(filterText, index) =
@ -231,7 +231,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
// We intercept this call only to get the initial extent
// of what was committed to the source buffer.
let result = decl.GetName(filterText, index)
PrettyNaming.AddBackticksToIdentifierIfNeeded result
PrettyNaming.NormalizeIdentifierBackticks result
override decl.IsCommitChar(commitCharacter) =
// Usual language identifier rules...
@ -246,7 +246,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
let compareStrings(s,t,l,b : bool) = System.String.Compare(s,0,t,0,l,b)
let tryFindDeclIndex text length ignoreCase =
decls
|> Array.tryFindIndex (fun d -> compareStrings(d.Name, text, length, ignoreCase) = 0)
|> Array.tryFindIndex (fun d -> compareStrings(d.NameInList, text, length, ignoreCase) = 0)
// The best match is the first item that begins with the longest prefix of the
// given word (value).
let rec findMatchOfLength len ignoreCase =
@ -259,9 +259,9 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
let firstMatchingLenChars = tryFindDeclIndex textSoFar len ignoreCase
match firstMatchingLenChars with
| Some index ->
lastBestMatch <- decls.[index].Name
lastBestMatch <- decls.[index].NameInList
let select = len = textSoFar.Length
if (index <> decls.Length- 1) && (compareStrings(decls.[index+1].Name , textSoFar, len, ignoreCase) = 0)
if (index <> decls.Length- 1) && (compareStrings(decls.[index+1].NameInList , textSoFar, len, ignoreCase) = 0)
then (index, false, select)
else (index, select, select)
| None ->
@ -278,7 +278,7 @@ type internal FSharpDeclarations_DEPRECATED(documentationBuilder, declarations:
// for example, "System.Console.WrL" will filter down to one, and still be a match, whereas
// "System.Console.WrLx" will filter down to one, but no longer be a match
decls.Length = 1 &&
AbstractPatternMatcher.Singleton.MatchSingleWordPattern(decls.[0].Name, textSoFar)<>null
AbstractPatternMatcher.Singleton.MatchSingleWordPattern(decls.[0].NameInList, textSoFar)<>null
)
shouldSelectItem <- preselect

Просмотреть файл

@ -428,38 +428,104 @@ module Test =
Assert.AreEqual(expected, quickInfo)
()
[<TestCase """
[<Test>]
let ``Automation.LetBindings.InModule``() =
let code = """
namespace FsTest
module Test =
let fu$$nc x = ()
""">]
[<TestCase """
namespace FsTest
module Test =
type T() =
let fu$$nc x = ()
""">]
[<TestCase """
namespace FsTest
module Test =
type T() =
static let fu$$nc x = ()
""">]
[<TestCase """
namespace FsTest
module Test =
do
let fu$$nc x = ()
()
""">]
let ``Automation.LetBindings`` code =
"""
let expectedSignature = "val func: x: 'a -> unit"
let tooltip = GetQuickInfoTextFromCode code
StringAssert.StartsWith(expectedSignature, tooltip)
()
[<Test>]
let ``Automation.LetBindings.InClass``() =
let code = """
namespace FsTest
module Test =
type T() =
let fu$$nc x = ()
"""
let expectedSignature = "val func: x: 'a -> unit"
let tooltip = GetQuickInfoTextFromCode code
StringAssert.StartsWith(expectedSignature, tooltip)
[<Test >]
let ``Automation.LetBindings.StaticLet``() =
let code = """
namespace FsTest
module Test =
type T() =
static let fu$$nc x = ()
"""
let expectedSignature = "val func: x: 'a -> unit"
let tooltip = GetQuickInfoTextFromCode code
StringAssert.StartsWith(expectedSignature, tooltip)
()
[<Test>]
let ``Automation.LetBindings.InDoBinding``() =
let code = """
namespace FsTest
module Test =
do
let fu$$nc x = ()
()
"""
let expectedSignature = "val func: x: 'a -> unit"
let tooltip = GetQuickInfoTextFromCode code
StringAssert.StartsWith(expectedSignature, tooltip)
()
[<Test>]
let ``Display names for exceptions with backticks preserve backticks``() =
let code = """
exception SomeError of ``thing wi$$th space``: string
"""
let expected = "``thing with space``"
let actual = GetQuickInfoTextFromCode code
StringAssert.Contains(expected, actual)
()
[<Test>]
let ``Display names for anonymous record fields with backticks preserve backticks``() =
let code = """
type R = {| ``thing wi$$th space``: string |}
"""
let expected = "``thing with space``"
let actual = GetQuickInfoTextFromCode code
StringAssert.Contains(expected, actual)
()
[<Test>]
let ``Display names identifiers for active patterns with backticks preserve backticks``() =
let code = """
let (|``Thing with space``|_|) x = if x % 2 = 0 then Some (x/2) else None
match 4 with
| ``Thing wi$$th space`` _ -> "yes"
| _ -> "no"
"""
let expected = "``Thing with space``"
let actual = GetQuickInfoTextFromCode code
StringAssert.Contains(expected, actual)
()

Просмотреть файл

@ -130,7 +130,7 @@ let assertSignatureHelpForMethodCalls (fileContents: string) (marker: string) (e
Assert.AreEqual(expected, actual)
let assertSignatureHelpForFunctionApplication (fileContents: string) (marker: string) expectedArgumentCount expectedArgumentIndex =
let assertSignatureHelpForFunctionApplication (fileContents: string) (marker: string) expectedArgumentCount expectedArgumentIndex expectedArgumentName =
let caretPosition = fileContents.LastIndexOf(marker) + marker.Length
let document, sourceText = RoslynTestHelpers.CreateDocument(filePath, fileContents)
@ -166,12 +166,15 @@ let assertSignatureHelpForFunctionApplication (fileContents: string) (marker: st
| Some sigHelp ->
Assert.AreEqual(expectedArgumentCount, sigHelp.ArgumentCount)
Assert.AreEqual(expectedArgumentIndex, sigHelp.ArgumentIndex)
Assert.AreEqual(1, sigHelp.SignatureHelpItems.Length)
Assert.IsTrue(expectedArgumentIndex < sigHelp.SignatureHelpItems[0].Parameters.Length)
Assert.AreEqual(expectedArgumentName, sigHelp.SignatureHelpItems[0].Parameters[expectedArgumentIndex].ParameterName)
[<TestFixture>]
module ``Gives signature help in method calls`` =
[<Test>]
let ``dot``() =
let ``dot``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -180,7 +183,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker None
[<Test>]
let ``System``() =
let ``System``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -189,7 +192,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker None
[<Test>]
let ``WriteLine``() =
let ``WriteLine``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -198,7 +201,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker None
[<Test>]
let ``open paren``() =
let ``open paren``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -207,7 +210,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 0, 2, Some "format"))
[<Test>]
let ``named arg``() =
let ``named arg``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -216,7 +219,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 0, 2, Some "format"))
[<Test>]
let ``comma``() =
let ``comma``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -225,7 +228,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker None
[<Test>]
let ``second comma``() =
let ``second comma``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -233,7 +236,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents """",""" (Some ("[7..64)", 1, 2, Some "arg0"))
[<Test>]
let ``second named arg``() =
let ``second named arg``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -242,7 +245,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 1, 2, Some "arg0"))
[<Test>]
let ``second named arg equals``() =
let ``second named arg equals``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -251,7 +254,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 1, 2, Some "arg0"))
[<Test>]
let ``World``() =
let ``World``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -260,7 +263,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
assertSignatureHelpForMethodCalls fileContents marker (Some ("[7..64)", 1, 2, Some "arg0"))
[<Test>]
let ``end paren``() =
let ``end paren``() : unit =
let fileContents = """
//1
System.Console.WriteLine(format="Hello, {0}",arg0="World")
@ -271,7 +274,7 @@ System.Console.WriteLine(format="Hello, {0}",arg0="World")
[<TestFixture>]
module ``Signature help with list literals, parens, etc`` =
[<Test>]
let ``Open paren``() =
let ``Open paren``() : unit =
let fileContents = """
//2
open System
@ -281,7 +284,7 @@ Console.WriteLine([(1,2)])
assertSignatureHelpForMethodCalls fileContents marker (Some ("[20..45)", 0, 0, None))
[<Test>]
let ``comma``() =
let ``comma``() : unit =
let fileContents = """
//2
open System
@ -291,7 +294,7 @@ Console.WriteLine([(1,2)])
assertSignatureHelpForMethodCalls fileContents marker None
[<Test>]
let ``list and tuple bracket pair start``() =
let ``list and tuple bracket pair start``() : unit =
let fileContents = """
//2
open System
@ -303,7 +306,7 @@ Console.WriteLine([(1,2)])
[<TestFixture>]
module ``Unfinished parentheses`` =
[<Test>]
let ``Unfinished parentheses``() =
let ``Unfinished parentheses``() : unit =
let fileContents = """
let _ = System.DateTime(
"""
@ -311,7 +314,7 @@ let _ = System.DateTime(
assertSignatureHelpForMethodCalls fileContents marker (Some ("[10..26)", 0, 0, None))
[<Test>]
let ``Unfinished parentheses with comma``() =
let ``Unfinished parentheses with comma``() : unit =
let fileContents = """
let _ = System.DateTime(1L,
"""
@ -319,7 +322,7 @@ let _ = System.DateTime(1L,
assertSignatureHelpForMethodCalls fileContents marker (Some ("[10..31)", 1, 2, None ))
[<Test>]
let ``type provider static parameter tests``() =
let ``type provider static parameter tests``() : unit =
// This is old code and I'm too lazy to move it all out. - Phillip Carter
let manyTestCases =
[
@ -379,34 +382,34 @@ type foo5 = N1.T<Param1=1,ParamIgnored= >
[<TestFixture>]
module ``Function argument applications`` =
[<Test>]
let ``single argument function application``() =
let ``single argument function application``() : unit =
let fileContents = """
sqrt
"""
let marker = "sqrt "
assertSignatureHelpForFunctionApplication fileContents marker 1 0
assertSignatureHelpForFunctionApplication fileContents marker 1 0 "value"
[<Test>]
let ``multi-argument function application``() =
let ``multi-argument function application``() : unit =
let fileContents = """
let add2 x y = x + y
add2 1
"""
let marker = "add2 1 "
assertSignatureHelpForFunctionApplication fileContents marker 2 1
assertSignatureHelpForFunctionApplication fileContents marker 2 1 "y"
[<Test>]
let ``qualified function application``() =
let ``qualified function application``() : unit =
let fileContents = """
module M =
let f x = x
M.f
"""
let marker = "M.f "
assertSignatureHelpForFunctionApplication fileContents marker 1 0
assertSignatureHelpForFunctionApplication fileContents marker 1 0 "x"
[<Test>]
let ``function application in single pipeline with no additional args``() =
let ``function application in single pipeline with no additional args``() : unit =
let fileContents = """
[1..10] |> id
"""
@ -445,35 +448,61 @@ M.f
Assert.True(sigHelp.IsNone, "No signature help is expected because there are no additional args to apply.")
[<Test>]
let ``function application in single pipeline with an additional argument``() =
let ``function application in single pipeline with an additional argument``() : unit =
let fileContents = """
[1..10] |> List.map
"""
let marker = "List.map "
assertSignatureHelpForFunctionApplication fileContents marker 1 0
assertSignatureHelpForFunctionApplication fileContents marker 1 0 "mapping"
[<Test>]
let ``function application in middle of pipeline with an additional argument``() =
let ``function application in middle of pipeline with an additional argument``() : unit =
let fileContents = """
[1..10]
|> List.map
|> List.filer (fun x -> x > 3)
"""
let marker = "List.map "
assertSignatureHelpForFunctionApplication fileContents marker 1 0
assertSignatureHelpForFunctionApplication fileContents marker 1 0 "mapping"
[<Test>]
let ``function application with function as parameter``() =
let ``function application with function as parameter``() : unit =
let fileContents = """
let derp (f: int -> int -> int) x = f x 1
derp
"""
let marker = "derp "
assertSignatureHelpForFunctionApplication fileContents marker 2 0
assertSignatureHelpForFunctionApplication fileContents marker 2 0 "f"
[<Test>]
let ``function application with function as second parameter 1``() : unit =
let fileContents = """
let derp (f: int -> int -> int) x = f x 1
let add x y = x + y
derp add
"""
let marker = "derp add "
assertSignatureHelpForFunctionApplication fileContents marker 2 1 "x"
[<Test>]
let ``function application with function as second parameter 2``() : unit =
let fileContents = """
let f (derp: int -> int) x = derp x
"""
let marker = "derp "
assertSignatureHelpForFunctionApplication fileContents marker 1 0 "arg0"
[<Test>]
let ``function application with curried function as parameter``() : unit =
let fileContents = """
let f (derp: int -> int -> int) x = derp x
"""
let marker = "derp x "
assertSignatureHelpForFunctionApplication fileContents marker 2 1 "arg1"
// migrated from legacy test
[<Test>]
let ``Multi.ReferenceToProjectLibrary``() =
let ``Multi.ReferenceToProjectLibrary``() : unit =
let completionNames = GetCompletionTypeNamesFromXmlString @"
<Projects>