Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Name resolution: report interfaces, report type arguments #15628

Closed
Closed
2 changes: 1 addition & 1 deletion src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,7 @@ module MutRecBindingChecking =

// Phase2B: typecheck the argument to an 'inherits' call and build the new object expr for the inherit-call
| Phase2AInherit (synBaseTy, arg, baseValOpt, m) ->
let baseTy, tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurence.Use WarnOnIWSAM.Yes envInstance tpenv synBaseTy
let baseTy, tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurence.UseInType WarnOnIWSAM.Yes envInstance tpenv synBaseTy
let baseTy = baseTy |> convertToTypeWithMetadataIfPossible g
let inheritsExpr, tpenv =
try
Expand Down
138 changes: 82 additions & 56 deletions src/Compiler/Checking/CheckExpressions.fs

Large diffs are not rendered by default.

34 changes: 25 additions & 9 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,7 @@ type ITypecheckResultsSink =

abstract NotifyExprHasType: TType * NameResolutionEnv * AccessorDomain * range -> unit

abstract NotifyNameResolution: pos * item: Item * TyparInstantiation * ItemOccurence * NameResolutionEnv * AccessorDomain * range * replace: bool -> unit
abstract NotifyNameResolution: pos * item: Item * TyparInstantiation * ItemOccurence * NameResolutionEnv * AccessorDomain * range * replace: (Item -> bool) option -> unit

abstract NotifyMethodGroupNameResolution : pos * item: Item * itemMethodGroup: Item * TyparInstantiation * ItemOccurence * NameResolutionEnv * AccessorDomain * range * replace: bool -> unit

Expand Down Expand Up @@ -2141,12 +2141,28 @@ type TcResultsSinkImpl(tcGlobals, ?sourceText: ISourceText) =
capturedExprTypings.Add((ty, nenv, ad, m))

member sink.NotifyNameResolution(endPos, item, tpinst, occurenceType, nenv, ad, m, replace) =
if allowedRange m then
if replace then
remove m
if isAlreadyDone endPos item m || not (allowedRange m) then () else

if not (isAlreadyDone endPos item m) then
capturedNameResolutions.Add(CapturedNameResolution(item, tpinst, occurenceType, nenv, ad, m))
let cnr = CapturedNameResolution(item, tpinst, occurenceType, nenv, ad, m)

match replace with
| None ->
capturedNameResolutions.Add(cnr)

| Some f ->
match item with
| Item.MethodGroup _ ->
match capturedMethodGroupResolutions.FindLastIndex(fun cnr -> equals cnr.Range m) with
| -1 -> ()
| i -> capturedMethodGroupResolutions.RemoveAt(i)
| _ -> ()

match capturedNameResolutions.FindLastIndex(fun cnr -> equals cnr.Range m) with
| i when i >= 0 ->
if f capturedNameResolutions[i].Item then
capturedNameResolutions[i] <- cnr
| _ ->
capturedNameResolutions.Add(cnr)

member sink.NotifyMethodGroupNameResolution(endPos, item, itemMethodGroup, tpinst, occurenceType, nenv, ad, m, replace) =
if allowedRange m then
Expand Down Expand Up @@ -2197,17 +2213,17 @@ let CallEnvSink (sink: TcResultsSink) (scopem, nenv, ad) =
let CallNameResolutionSink (sink: TcResultsSink) (m: range, nenv, item, tpinst, occurenceType, ad) =
match sink.CurrentSink with
| None -> ()
| Some sink -> sink.NotifyNameResolution(m.End, item, tpinst, occurenceType, nenv, ad, m, false)
| Some sink -> sink.NotifyNameResolution(m.End, item, tpinst, occurenceType, nenv, ad, m, None)

let CallMethodGroupNameResolutionSink (sink: TcResultsSink) (m: range, nenv, item, itemMethodGroup, tpinst, occurenceType, ad) =
match sink.CurrentSink with
| None -> ()
| Some sink -> sink.NotifyMethodGroupNameResolution(m.End, item, itemMethodGroup, tpinst, occurenceType, nenv, ad, m, false)

let CallNameResolutionSinkReplacing (sink: TcResultsSink) (m: range, nenv, item, tpinst, occurenceType, ad) =
let CallNameResolutionSinkReplacing (sink: TcResultsSink) f (m: range, nenv, item, tpinst, occurenceType, ad) =
match sink.CurrentSink with
| None -> ()
| Some sink -> sink.NotifyNameResolution(m.End, item, tpinst, occurenceType, nenv, ad, m, true)
| Some sink -> sink.NotifyNameResolution(m.End, item, tpinst, occurenceType, nenv, ad, m, Some f)

/// Report a specific expression typing at a source range
let CallExprHasTypeSink (sink: TcResultsSink) (m: range, nenv, ty, ad) =
Expand Down
15 changes: 13 additions & 2 deletions src/Compiler/Checking/NameResolution.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,15 @@ type ITypecheckResultsSink =

/// Record that a name resolution occurred at a specific location in the source
abstract NotifyNameResolution:
pos * Item * TyparInstantiation * ItemOccurence * NameResolutionEnv * AccessorDomain * range * bool -> unit
pos *
Item *
TyparInstantiation *
ItemOccurence *
NameResolutionEnv *
AccessorDomain *
range *
(Item -> bool) option ->
unit

/// Record that a method group name resolution occurred at a specific location in the source
abstract NotifyMethodGroupNameResolution:
Expand Down Expand Up @@ -619,7 +627,10 @@ val internal CallMethodGroupNameResolutionSink:

/// Report a specific name resolution at a source range, replacing any previous resolutions
val internal CallNameResolutionSinkReplacing:
TcResultsSink -> range * NameResolutionEnv * Item * TyparInstantiation * ItemOccurence * AccessorDomain -> unit
TcResultsSink ->
(Item -> bool) ->
range * NameResolutionEnv * Item * TyparInstantiation * ItemOccurence * AccessorDomain ->
unit

/// Report a specific name resolution at a source range
val internal CallExprHasTypeSink: TcResultsSink -> range * NameResolutionEnv * TType * AccessorDomain -> unit
Expand Down
6 changes: 6 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ type ValRemap = ValMap<ValRef>
let emptyTyconRefRemap: TyconRefRemap = TyconRefMap<_>.Empty
let emptyTyparInst = ([]: TyparInstantiation)

let getInst (ty: TType) =
match stripTyparEqns ty with
| TType_app(tcref, typeArgs, _) ->
List.zip tcref.Deref.TyparsNoRange typeArgs
| _ -> []

[<NoEquality; NoComparison>]
type Remap =
{ tpinst: TyparInstantiation
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ val mkTyconRefInst: TyconRef -> TypeInst -> TyparInstantiation

val emptyTyparInst: TyparInstantiation

val getInst: TType -> TyparInstantiation

val instType: TyparInstantiation -> TType -> TType

val instTypes: TyparInstantiation -> TypeInst -> TypeInst
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,23 @@ let createProject() = SyntheticProject.Create(impFile())
[<Fact>]
let ``Finding usage of type via GetUsesOfSymbolInFile should also find it's constructors`` () =
createProject().Workflow
{
{
checkFile "First" (fun (typeCheckResult: FSharpCheckFileResults) ->

let symbolUse = typeCheckResult.GetSymbolUseAtLocation(7, 11, "type MyType() =", ["MyType"]).Value
let references =
typeCheckResult.GetUsesOfSymbolInFile(symbolUse.Symbol)
typeCheckResult.GetUsesOfSymbolInFile(symbolUse.Symbol)
|> Array.sortBy (fun su -> su.Range.StartLine)
|> Array.map (fun su -> su.Range.StartLine, su.Range.StartColumn, su.Range.EndColumn, deriveOccurence su)

Assert.Equal<(int*int*int*Occurence)>(
[| 7,5,11,Definition
8,25,31,InType
10,8,14,Use
11,12,18,Use
|],references) )
Assert.Equal<int * int * int * Occurence>(
[| 7, 5, 11, Definition
8, 25, 31, InType
10, 8, 14, Use
11, 12, 18, InType
11, 12, 18, Use
|], references)
)
}


Expand Down
3 changes: 1 addition & 2 deletions tests/service/CSharpProjectAnalysis.fs
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ let _ = CSharpGenericOuterClass<int>.InnerClass.StaticMember()
|> shouldEqual
[|"FSharp"; "Compiler"; "Service"; "Tests"; "FSharp"; "member .ctor"; "int";
"CSharpGenericOuterClass`1"; "CSharpGenericOuterClass`1"; "int";
"CSharpGenericOuterClass`1"; "InnerEnum"; "field Case1";
"CSharpGenericOuterClass`1"; "int"; "CSharpGenericOuterClass`1"; "InnerClass";
"InnerEnum"; "field Case1"; "CSharpGenericOuterClass`1"; "int"; "InnerClass";
"member StaticMember"; "NestedEnumClass"|]

[<Test>]
Expand Down
2 changes: 1 addition & 1 deletion tests/service/Common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ let inline dumpDiagnostics (results: FSharpCheckFileResults) =
|> List.ofArray

let getSymbolUses (results: FSharpCheckFileResults) =
results.GetAllUsesOfAllSymbolsInFile()
results.GetAllUsesOfAllSymbolsInFile() |> List.ofSeq

let getSymbolUsesFromSource (source: string) =
let _, typeCheckResults = getParseAndCheckResults source
Expand Down
Loading