Skip to content

Commit

Permalink
Fix autocomplete and other glitches for static method args
Browse files Browse the repository at this point in the history
  • Loading branch information
dsyme committed Mar 22, 2016
1 parent 8418ec4 commit 73c0796
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 371 deletions.
1 change: 1 addition & 0 deletions src/fsharp/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1271,3 +1271,4 @@ estApplyStaticArgumentsForMethodNotImplemented,"A type provider implemented GetS
3194,optsResponseFileNotFound,"Response file '%s' not found in '%s'"
3195,optsResponseFileNameInvalid,"Response file name '%s' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long"
3196,fsharpCoreNotFoundToBeCopied,"Cannot find FSharp.Core.dll in compiler's directory"
3197,etMissingStaticArgumentsToMethod,"This provided method requires static parameters"
84 changes: 60 additions & 24 deletions src/fsharp/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ type Item =
| Event of EventInfo
/// Represents the resolution of a name to a property
| Property of string * PropInfo list
/// Represents the resolution of a name to a group of methods
| MethodGroup of string * MethInfo list
/// Represents the resolution of a name to a group of methods.
| MethodGroup of displayName: string * methods: MethInfo list * uninstantiatedMethodOpt: MethInfo option
/// Represents the resolution of a name to a constructor
| CtorGroup of string * MethInfo list
/// Represents the resolution of a name to the fake constructor simulated for an interface type.
Expand Down Expand Up @@ -195,7 +195,7 @@ type Item =

static member MakeMethGroup (nm,minfos:MethInfo list) =
let minfos = minfos |> List.sortBy (fun minfo -> minfo.NumArgs |> List.sum)
Item.MethodGroup (nm,minfos)
Item.MethodGroup (nm,minfos,None)

static member MakeCtorGroup (nm,minfos:MethInfo list) =
let minfos = minfos |> List.sortBy (fun minfo -> minfo.NumArgs |> List.sum)
Expand All @@ -212,7 +212,7 @@ type Item =
| Item.ILField finfo -> finfo.FieldName
| Item.Event einfo -> einfo.EventName
| Item.Property(nm,_) -> nm
| Item.MethodGroup(nm,_) -> nm
| Item.MethodGroup(nm,_,_) -> nm
| Item.CtorGroup(nm,_) -> DemangleGenericTypeName nm
| Item.FakeInterfaceCtor (AbbrevOrAppTy tcref)
| Item.DelegateCtor (AbbrevOrAppTy tcref) -> DemangleGenericTypeName tcref.DisplayName
Expand Down Expand Up @@ -1106,7 +1106,7 @@ type ItemOccurence =
type ITypecheckResultsSink =
abstract NotifyEnvWithScope : range * NameResolutionEnv * AccessorDomain -> unit
abstract NotifyExprHasType : pos * TType * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit
abstract NotifyNameResolution : pos * Item * Item * ItemOccurence * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit
abstract NotifyNameResolution : pos * Item * Item * ItemOccurence * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range * bool -> unit
abstract NotifyFormatSpecifierLocation : range -> unit
abstract CurrentSource : string option

Expand Down Expand Up @@ -1140,12 +1140,12 @@ let rec (|FSharpPropertyUse|_|) (item : Item) =

let (|MethodUse|_|) (item : Item) =
match item with
| Item.MethodGroup(_, [minfo]) -> Some(minfo)
| Item.MethodGroup(_, [minfo],_) -> Some(minfo)
| _ -> None

let (|FSharpMethodUse|_|) (item : Item) =
match item with
| Item.MethodGroup(_, [ValRefOfMeth vref]) -> Some(vref)
| Item.MethodGroup(_, [ValRefOfMeth vref],_) -> Some(vref)
| Item.Value(vref) when vref.IsMember -> Some(vref)
| _ -> None

Expand Down Expand Up @@ -1346,7 +1346,7 @@ type TcResultsSinkImpl(g, ?source: string) =
if allowedRange m then
capturedExprTypings.Add((endPos,ty,denv,nenv,ad,m))

member sink.NotifyNameResolution(endPos,item,itemMethodGroup,occurenceType,denv,nenv,ad,m) =
member sink.NotifyNameResolution(endPos,item,itemMethodGroup,occurenceType,denv,nenv,ad,m,replace) =
// Desugaring some F# constructs (notably computation expressions with custom operators)
// results in duplication of textual variables. So we ensure we never record two name resolutions
// for the same identifier at the same location.
Expand All @@ -1365,6 +1365,10 @@ type TcResultsSinkImpl(g, ?source: string) =
res
| _ -> false

if replace then
capturedNameResolutions.RemoveAll(fun cnr -> cnr.Range = m) |> ignore
capturedMethodGroupResolutions.RemoveAll(fun cnr -> cnr.Range = m) |> ignore

if not alreadyDone then
capturedNameResolutions.Add(CapturedNameResolution(endPos,item,occurenceType,denv,nenv,ad,m))
capturedMethodGroupResolutions.Add(CapturedNameResolution(endPos,itemMethodGroup,occurenceType,denv,nenv,ad,m))
Expand Down Expand Up @@ -1405,7 +1409,12 @@ let CallEnvSink (sink:TcResultsSink) (scopem,nenv,ad) =
let CallNameResolutionSink (sink:TcResultsSink) (m:range,nenv,item,itemMethodGroup,occurenceType,denv,ad) =
match sink.CurrentSink with
| None -> ()
| Some sink -> sink.NotifyNameResolution(m.End,item,itemMethodGroup,occurenceType,denv,nenv,ad,m)
| Some sink -> sink.NotifyNameResolution(m.End,item,itemMethodGroup,occurenceType,denv,nenv,ad,m,false)

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

/// Report a specific expression typing at a source range
let CallExprHasTypeSink (sink:TcResultsSink) (m:range,nenv,typ,denv,ad) =
Expand Down Expand Up @@ -1434,7 +1443,7 @@ let CheckAllTyparsInferrable amap m item =
let free = Zset.diff freeInDeclaringType.FreeTypars freeInArgsAndRetType.FreeTypars
free.IsEmpty)

| Item.MethodGroup(_,minfos) ->
| Item.MethodGroup(_,minfos,_) ->
minfos |> List.forall (fun minfo ->
minfo.IsExtensionMember ||
let fminst = minfo.FormalMethodInst
Expand Down Expand Up @@ -2571,15 +2580,15 @@ let ComputeItemRange wholem (lid: Ident list) rest =
let FilterMethodGroups (ncenv:NameResolver) itemRange item staticOnly =
match item with
| Item.MethodGroup(nm, minfos) ->
| Item.MethodGroup(nm, minfos, orig) ->
let minfos = minfos |> List.filter (fun minfo ->
staticOnly = (minfo.GetObjArgTypes(ncenv.amap, itemRange, minfo.FormalMethodInst) |> isNil))
Item.MethodGroup(nm, minfos)
Item.MethodGroup(nm, minfos, orig)
| item -> item

let NeedsOverloadResolution namedItem =
match namedItem with
| Item.MethodGroup(_,_::_::_)
| Item.MethodGroup(_,_::_::_,_)
| Item.CtorGroup(_,_::_::_)
| Item.Property(_,_::_::_) -> true
| _ -> false
Expand Down Expand Up @@ -2632,7 +2641,7 @@ let ResolveLongIdentAsExprAndComputeRange (sink:TcResultsSink) (ncenv:NameResolv

let (|NonOverridable|_|) namedItem =
match namedItem with
| Item.MethodGroup(_,minfos) when minfos |> List.exists(fun minfo -> minfo.IsVirtual || minfo.IsAbstract) -> None
| Item.MethodGroup(_,minfos,_) when minfos |> List.exists(fun minfo -> minfo.IsVirtual || minfo.IsAbstract) -> None
| Item.Property(_,pinfos) when pinfos |> List.exists(fun pinfo -> pinfo.IsVirtualProperty) -> None
| _ -> Some ()

Expand Down Expand Up @@ -2905,16 +2914,43 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso
AllMethInfosOfTypeInScope ncenv.InfoReader nenv (None,ad) PreferOverrides m typ
|> List.filter minfoFilter

let addersAndRemovers =
pinfoItems
|> List.map (function Item.Event(FSEvent(_,_,addValRef,removeValRef)) -> [addValRef.LogicalName;removeValRef.LogicalName] | _ -> [])
|> List.concat

match addersAndRemovers with
| [] -> minfos
| addersAndRemovers ->
let isNotAdderOrRemover (minfo: MethInfo) = not(addersAndRemovers |> List.exists (fun ar -> ar = minfo.LogicalName))
List.filter isNotAdderOrRemover minfos
let minfos =
let addersAndRemovers =
pinfoItems
|> List.map (function Item.Event(FSEvent(_,_,addValRef,removeValRef)) -> [addValRef.LogicalName;removeValRef.LogicalName] | _ -> [])
|> List.concat
|> set

if addersAndRemovers.IsEmpty then minfos
else minfos |> List.filter (fun minfo -> not (addersAndRemovers.Contains minfo.LogicalName))

// Filter out the ones with mangled names from applying static parameters
let minfos =
let methsWithStaticParams =
minfos
|> List.filter (fun minfo ->
match minfo.ProvidedStaticParameterInfo with
| Some (_methBeforeArguments, staticParams) -> staticParams.Length <> 0
| _ -> false)
|> List.map (fun minfo -> minfo.DisplayName)

if methsWithStaticParams.IsEmpty then minfos
else minfos |> List.filter (fun minfo ->
let nm = minfo.LogicalName
not (nm.Contains "," && methsWithStaticParams |> List.exists (fun m -> nm.StartsWith(m))))
minfos
(*
and TryTcMethodAppToStaticConstantArgs cenv env tpenv (minfos: MethInfo list, argsOpt, mExprAndArg, mItem) =
match minfos, argsOpt with
| [minfo], Some (args,_) ->
match minfo.ProvidedStaticParameterInfo with
| Some (methBeforeArguments, staticParams) ->
let providedMethAfterStaticArguments = TcProvidedMethodAppToStaticConstantArgs cenv env tpenv (minfo, methBeforeArguments, staticParams, args, mExprAndArg)
let minfoAfterStaticArguments = ProvidedMeth(cenv.amap,providedMethAfterStaticArguments,minfo.ExtensionMemberPriorityOption,mItem)
Some minfoAfterStaticArguments
| _ -> None
| _ -> None
*)

else []
// Partition methods into overload sets
Expand Down
7 changes: 5 additions & 2 deletions src/fsharp/NameResolution.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ type Item =
| ILField of ILFieldInfo
| Event of EventInfo
| Property of string * PropInfo list
| MethodGroup of string * MethInfo list
| MethodGroup of displayName: string * methods: MethInfo list * uninstantiatedMethodOpt: MethInfo option
| CtorGroup of string * MethInfo list
| FakeInterfaceCtor of TType
| DelegateCtor of TType
Expand Down Expand Up @@ -261,7 +261,7 @@ type ITypecheckResultsSink =
abstract NotifyExprHasType : pos * TType * DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit

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

/// Record that a printf format specifier occurred at a specific location in the source
abstract NotifyFormatSpecifierLocation : range -> unit
Expand Down Expand Up @@ -301,6 +301,9 @@ val internal CallEnvSink : TcResultsSink -> range * NameResolutio
/// Report a specific name resolution at a source range
val internal CallNameResolutionSink : TcResultsSink -> range * NameResolutionEnv * Item * Item * ItemOccurence * DisplayEnv * AccessorDomain -> unit

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

/// Report a specific name resolution at a source range
val internal CallExprHasTypeSink : TcResultsSink -> range * NameResolutionEnv * TType * DisplayEnv * AccessorDomain -> unit

Expand Down
Loading

0 comments on commit 73c0796

Please sign in to comment.