зеркало из https://github.com/dotnet/fsharp.git
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:
Родитель
2f3a78a399
Коммит
eb72891948
|
@ -123,3 +123,5 @@ nCrunchTemp_*
|
|||
|
||||
/test.fs
|
||||
/test.fsx
|
||||
|
||||
tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.actual
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче