diff --git a/eng/Versions.props b/eng/Versions.props index 3a05092d768..d6cedf2f55a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -23,7 +23,7 @@ $(FSProductVersion).0 16 - 0 + 1 $(VSMajorVersion).0 $(VSMajorVersion).$(VSMinorVersion).0 $(VSAssemblyVersion).0 diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index ee8cddf8a28..a7b757568f1 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -1586,7 +1586,7 @@ type TcResultsSinkImpl(g, ?sourceText: ISourceText) = // results in duplication of textual variables. So we ensure we never record two name resolutions // for the same identifier at the same location. if allowedRange m then - if replace then + if replace then capturedNameResolutions.RemoveAll(fun cnr -> Range.equals cnr.Range m) |> ignore capturedMethodGroupResolutions.RemoveAll(fun cnr -> Range.equals cnr.Range m) |> ignore else diff --git a/src/fsharp/NameResolution.fsi b/src/fsharp/NameResolution.fsi index a790947ece4..4eff7f15635 100755 --- a/src/fsharp/NameResolution.fsi +++ b/src/fsharp/NameResolution.fsi @@ -1,542 +1,542 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module internal FSharp.Compiler.NameResolution - -open FSharp.Compiler -open FSharp.Compiler.AccessibilityLogic -open FSharp.Compiler.Ast -open FSharp.Compiler.Infos -open FSharp.Compiler.Range -open FSharp.Compiler.Import -open FSharp.Compiler.InfoReader -open FSharp.Compiler.Tast -open FSharp.Compiler.Tastops -open FSharp.Compiler.TcGlobals -open FSharp.Compiler.AbstractIL.Internal.Library -open FSharp.Compiler.PrettyNaming -open FSharp.Compiler.Text - -/// A NameResolver is a context for name resolution. It primarily holds an InfoReader. -type NameResolver = - new : g:TcGlobals * amap:ImportMap * infoReader:InfoReader * instantiationGenerator:(range -> Typars -> TypeInst) -> NameResolver - member InfoReader : InfoReader - member amap : ImportMap - member g : TcGlobals - -/// Get the active pattern elements defined in a module, if any. Cache in the slot in the module type. -val ActivePatternElemsOfModuleOrNamespace : ModuleOrNamespaceRef -> NameMap - -[] -/// Represents the item with which a named argument is associated. -type ArgumentContainer = - /// The named argument is an argument of a method - | Method of MethInfo - /// The named argument is a static parameter to a provided type or a parameter to an F# exception constructor - | Type of TyconRef - /// The named argument is a static parameter to a union case constructor - | UnionCase of UnionCaseInfo - -//--------------------------------------------------------------------------- -// -//------------------------------------------------------------------------- - -/// Detect a use of a nominal type, including type abbreviations. -/// When reporting symbols, we care about abbreviations, e.g. 'int' and 'int32' count as two separate symbols. -val (|AbbrevOrAppTy|_|) : TType -> TyconRef option - -[] -/// Represents an item that results from name resolution -type Item = - /// Represents the resolution of a name to an F# value or function. - | Value of ValRef - - /// Represents the resolution of a name to an F# union case. - | UnionCase of UnionCaseInfo * bool - - /// Represents the resolution of a name to an F# active pattern result. - | ActivePatternResult of ActivePatternInfo * TType * int * range - - /// Represents the resolution of a name to an F# active pattern case within the body of an active pattern. - | ActivePatternCase of ActivePatternElemRef - - /// Represents the resolution of a name to an F# exception definition. - | ExnCase of TyconRef - - /// Represents the resolution of a name to an F# record field. - | RecdField of RecdFieldInfo - - /// Represents the resolution of a name to a field of an anonymous record type. - | AnonRecdField of AnonRecdTypeInfo * TTypes * int * range - - // The following are never in the items table but are valid results of binding - // an identifier in different circumstances. - - /// Represents the resolution of a name at the point of its own definition. - | NewDef of Ident - - /// Represents the resolution of a name to a .NET field - | ILField of ILFieldInfo - - /// Represents the resolution of a name to an event - | 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 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. - | FakeInterfaceCtor of TType - - /// Represents the resolution of a name to a delegate - | DelegateCtor of TType - - /// Represents the resolution of a name to a group of types - | Types of string * TType list - - /// CustomOperation(nm, helpText, methInfo) - /// - /// Used to indicate the availability or resolution of a custom query operation such as 'sortBy' or 'where' in computation expression syntax - | CustomOperation of string * (unit -> string option) * MethInfo option - - /// Represents the resolution of a name to a custom builder in the F# computation expression syntax - | CustomBuilder of string * ValRef - - /// Represents the resolution of a name to a type variable - | TypeVar of string * Typar - - /// Represents the resolution of a name to a module or namespace - | ModuleOrNamespaces of Tast.ModuleOrNamespaceRef list - - /// Represents the resolution of a name to an operator - | ImplicitOp of Ident * TraitConstraintSln option ref - - /// Represents the resolution of a name to a named argument - | ArgName of Ident * TType * ArgumentContainer option - - /// Represents the resolution of a name to a named property setter - | SetterArg of Ident * Item - - /// Represents the potential resolution of an unqualified name to a type. - | UnqualifiedType of TyconRef list - - member DisplayName : string - -[] -/// Pairs an Item with a TyparInst showing how generic type variables of the item are instantiated at -/// a particular usage point. -type ItemWithInst = - { Item : Item - TyparInst: TyparInst } - -val (|ItemWithInst|) : ItemWithInst -> Item * TyparInst -val ItemWithNoInst : Item -> ItemWithInst - -/// Represents a record field resolution and the information if the usage is deprecated. -type FieldResolution = FieldResolution of RecdFieldRef * bool - -/// Information about an extension member held in the name resolution environment -[] -type ExtensionMember - -/// The environment of information used to resolve names -[] -type NameResolutionEnv = - {eDisplayEnv: DisplayEnv - eUnqualifiedItems: LayeredMap - ePatItems: NameMap - eModulesAndNamespaces: NameMultiMap - eFullyQualifiedModulesAndNamespaces: NameMultiMap - eFieldLabels: NameMultiMap - eTyconsByAccessNames: LayeredMultiMap - eFullyQualifiedTyconsByAccessNames: LayeredMultiMap - eTyconsByDemangledNameAndArity: LayeredMap - eFullyQualifiedTyconsByDemangledNameAndArity: LayeredMap - eIndexedExtensionMembers: TyconRefMultiMap - eUnindexedExtensionMembers: ExtensionMember list - eTypars: NameMap } - static member Empty : g:TcGlobals -> NameResolutionEnv - member DisplayEnv : DisplayEnv - member FindUnqualifiedItem : string -> Item - -type FullyQualifiedFlag = - | FullyQualified - | OpenQualified - -[] -type BulkAdd = Yes | No - -/// Find a field in anonymous record type -val internal TryFindAnonRecdFieldOfType : TcGlobals -> TType -> string -> Item option - -/// Add extra items to the environment for Visual Studio, e.g. static members -val internal AddFakeNamedValRefToNameEnv : string -> NameResolutionEnv -> ValRef -> NameResolutionEnv - -/// Add some extra items to the environment for Visual Studio, e.g. record members -val internal AddFakeNameToNameEnv : string -> NameResolutionEnv -> Item -> NameResolutionEnv - -/// Add a single F# value to the environment. -val internal AddValRefToNameEnv : NameResolutionEnv -> ValRef -> NameResolutionEnv - -/// Add active pattern result tags to the environment. -val internal AddActivePatternResultTagsToNameEnv : ActivePatternInfo -> NameResolutionEnv -> TType -> range -> NameResolutionEnv - -/// Add a list of type definitions to the name resolution environment -val internal AddTyconRefsToNameEnv : BulkAdd -> bool -> TcGlobals -> ImportMap -> range -> bool -> NameResolutionEnv -> TyconRef list -> NameResolutionEnv - -/// Add an F# exception definition to the name resolution environment -val internal AddExceptionDeclsToNameEnv : BulkAdd -> NameResolutionEnv -> TyconRef -> NameResolutionEnv - -/// Add a module abbreviation to the name resolution environment -val internal AddModuleAbbrevToNameEnv : Ident -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv - -/// Add a list of module or namespace to the name resolution environment, including any sub-modules marked 'AutoOpen' -val internal AddModuleOrNamespaceRefsToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv - -/// Add a single modules or namespace to the name resolution environment -val internal AddModuleOrNamespaceRefToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef -> NameResolutionEnv - -/// Add a list of modules or namespaces to the name resolution environment -val internal AddModulesAndNamespacesContentsToNameEnv : TcGlobals -> ImportMap -> AccessorDomain -> range -> bool -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv - -/// A flag which indicates if it is an error to have two declared type parameters with identical names -/// in the name resolution environment. -type CheckForDuplicateTyparFlag = - | CheckForDuplicateTypars - | NoCheckForDuplicateTypars - -/// Add some declared type parameters to the name resolution environment -val internal AddDeclaredTyparsToNameEnv : CheckForDuplicateTyparFlag -> NameResolutionEnv -> Typar list -> NameResolutionEnv - -/// Qualified lookup of type names in the environment -val internal LookupTypeNameInEnvNoArity : FullyQualifiedFlag -> string -> NameResolutionEnv -> TyconRef list - -/// Indicates whether we are resolving type names to type definitions or to constructor methods. -type TypeNameResolutionFlag = - /// Indicates we are resolving type names to constructor methods. - | ResolveTypeNamesToCtors - /// Indicates we are resolving type names to type definitions - | ResolveTypeNamesToTypeRefs - -/// Represents information about the generic argument count of a type name when resolving it. -/// -/// In some situations we resolve "List" to any type definition with that name regardless of the number -/// of generic arguments. In others, we know precisely how many generic arguments are needed. -[] -type TypeNameResolutionStaticArgsInfo = - /// Indicates definite knowledge of empty type arguments, i.e. the logical equivalent of name< > - static member DefiniteEmpty : TypeNameResolutionStaticArgsInfo - /// Deduce definite knowledge of type arguments - static member FromTyArgs : numTyArgs:int -> TypeNameResolutionStaticArgsInfo - -/// Represents information which guides name resolution of types. -[] -type TypeNameResolutionInfo = - | TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo - static member Default : TypeNameResolutionInfo - static member ResolveToTypeRefs : TypeNameResolutionStaticArgsInfo -> TypeNameResolutionInfo - -/// Represents the kind of the occurrence when reporting a name in name resolution -[] -type internal ItemOccurence = - | Binding - | Use - | UseInType - | UseInAttribute - | Pattern - | Implemented - | RelatedText - | Open - -/// Check for equality, up to signature matching -val ItemsAreEffectivelyEqual : TcGlobals -> Item -> Item -> bool - -/// Hash compatible with ItemsAreEffectivelyEqual -val ItemsAreEffectivelyEqualHash : TcGlobals -> Item -> int - -[] -type internal CapturedNameResolution = - /// line and column - member Pos : pos - - /// Named item - member Item : Item - - /// The active instantiation for any generic type parameters - member ItemWithInst: ItemWithInst - - /// Information about the occurrence of the symbol - member ItemOccurence : ItemOccurence - - /// Information about printing. For example, should redundant keywords be hidden? - member DisplayEnv : DisplayEnv - - /// Naming environment--for example, currently open namespaces. - member NameResolutionEnv : NameResolutionEnv - - /// The access rights of code at the location - member AccessorDomain : AccessorDomain - - /// The starting and ending position - member Range : range - -[] -type internal TcResolutions = - - /// Name resolution environments for every interesting region in the file. These regions may - /// overlap, in which case the smallest region applicable should be used. - member CapturedEnvs : ResizeArray - - /// Information of exact types found for expressions, that can be to the left of a dot. - /// typ - the inferred type for an expression - member CapturedExpressionTypings : ResizeArray - - /// Exact name resolutions - member CapturedNameResolutions : ResizeArray - - /// Represents all the resolutions of names to groups of methods. - member CapturedMethodGroupResolutions : ResizeArray - - /// Represents the empty set of resolutions - static member Empty : TcResolutions - - -[] -type TcSymbolUseData = - { Item: Item - ItemOccurence: ItemOccurence - DisplayEnv: DisplayEnv - Range: range } - -[] -/// Represents container for all name resolutions that were met so far when typechecking some particular file -type internal TcSymbolUses = - - /// Get all the uses of a particular item within the file - member GetUsesOfSymbol : Item -> TcSymbolUseData[] - - /// All the uses of all items within the file - member AllUsesOfSymbols : TcSymbolUseData[][] - - /// Get the locations of all the printf format specifiers in the file - member GetFormatSpecifierLocationsAndArity : unit -> (range * int)[] - -/// Represents open declaration statement. -type internal OpenDeclaration = - { /// Long identifier as it's presented in soruce code. - LongId: Ident list - - /// Full range of the open declaration. - Range : range option - - /// Modules or namespaces which is opened with this declaration. - Modules: ModuleOrNamespaceRef list - - /// Scope in which open declaration is visible. - AppliedScope: range - - /// If it's `namespace Xxx.Yyy` declaration. - IsOwnNamespace: bool } - - /// Create a new instance of OpenDeclaration. - static member Create : longId: Ident list * modules: ModuleOrNamespaceRef list * appliedScope: range * isOwnNamespace: bool -> OpenDeclaration - -/// Source text and an array of line end positions, used for format string parsing -type FormatStringCheckContext = - { /// Source text - SourceText: ISourceText - /// Array of line start positions - LineStartPositions: int[] } - -/// An abstract type for reporting the results of name resolution and type checking -type ITypecheckResultsSink = - - /// Record that an environment is active over the given scope range - abstract NotifyEnvWithScope : range * NameResolutionEnv * AccessorDomain -> unit - - /// Record that an expression has a specific type at the given range. - 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 * TyparInst * ItemOccurence * DisplayEnv * NameResolutionEnv * AccessorDomain * range * bool -> unit - - /// Record that a printf format specifier occurred at a specific location in the source - abstract NotifyFormatSpecifierLocation : range * int -> unit - - /// Record that an open declaration occured in a given scope range - abstract NotifyOpenDeclaration : OpenDeclaration -> unit - - /// Get the current source - abstract CurrentSourceText : ISourceText option - - /// Cached line-end normalized source text and an array of line end positions, used for format string parsing - abstract FormatStringCheckContext : FormatStringCheckContext option - -/// An implementation of ITypecheckResultsSink to collect information during type checking -type internal TcResultsSinkImpl = - - /// Create a TcResultsSinkImpl - new : tcGlobals : TcGlobals * ?sourceText: ISourceText -> TcResultsSinkImpl - - /// Get all the resolutions reported to the sink - member GetResolutions : unit -> TcResolutions - - /// Get all the uses of all symbols reported to the sink - member GetSymbolUses : unit -> TcSymbolUses - - /// Get all open declarations reported to the sink - member GetOpenDeclarations : unit -> OpenDeclaration[] - - interface ITypecheckResultsSink - -/// An abstract type for reporting the results of name resolution and type checking, and which allows -/// temporary suspension and/or redirection of reporting. -type TcResultsSink = - { mutable CurrentSink : ITypecheckResultsSink option } - static member NoSink : TcResultsSink - static member WithSink : ITypecheckResultsSink -> TcResultsSink - -/// Temporarily redirect reporting of name resolution and type checking results -val internal WithNewTypecheckResultsSink : ITypecheckResultsSink * TcResultsSink -> System.IDisposable - -/// Temporarily suspend reporting of name resolution and type checking results -val internal TemporarilySuspendReportingTypecheckResultsToSink : TcResultsSink -> System.IDisposable - -/// Report the active name resolution environment for a source range -val internal CallEnvSink : TcResultsSink -> range * NameResolutionEnv * AccessorDomain -> unit - -/// Report a specific name resolution at a source range -val internal CallNameResolutionSink : TcResultsSink -> range * NameResolutionEnv * Item * Item * TyparInst * 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 * TyparInst * ItemOccurence * DisplayEnv * AccessorDomain -> unit - -/// Report a specific name resolution at a source range -val internal CallExprHasTypeSink : TcResultsSink -> range * NameResolutionEnv * TType * DisplayEnv * AccessorDomain -> unit - -/// Report an open declaration -val internal CallOpenDeclarationSink : TcResultsSink -> OpenDeclaration -> unit - -/// Get all the available properties of a type (both intrinsic and extension) -val internal AllPropInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> FindMemberFlag -> range -> TType -> PropInfo list - -/// Get all the available properties of a type (only extension) -val internal ExtensionPropInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> range -> TType -> PropInfo list - -/// Get the available methods of a type (both declared and inherited) -val internal AllMethInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> FindMemberFlag -> range -> TType -> MethInfo list - -/// Used to report an error condition where name resolution failed due to an indeterminate type -exception internal IndeterminateType of range - -/// Used to report a warning condition for the use of upper-case identifiers in patterns -exception internal UpperCaseIdentifierInPattern of range - -/// Generate a new reference to a record field with a fresh type instantiation -val FreshenRecdFieldRef :NameResolver -> Range.range -> Tast.RecdFieldRef -> Item - -/// Indicates the kind of lookup being performed. Note, this type should be made private to nameres.fs. -[] -type LookupKind = - | RecdField - | Pattern - | Expr - | Type - | Ctor - - -/// Indicates if a warning should be given for the use of upper-case identifiers in patterns -type WarnOnUpperFlag = - | WarnOnUpperCase - | AllIdsOK - -/// Indicates whether we permit a direct reference to a type generator. Only set when resolving the -/// right-hand-side of a [] declaration. -[] -type PermitDirectReferenceToGeneratedType = - | Yes - | No - -/// Indicates if we only need one result or all possible results from a resolution. -[] -type ResultCollectionSettings = -| AllResults -| AtMostOneResult - -/// Resolve a long identifier to a namespace or module. -val internal ResolveLongIndentAsModuleOrNamespace : TcResultsSink -> ResultCollectionSettings -> Import.ImportMap -> range -> bool -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident -> Ident list -> isOpenDecl: bool -> ResultOrException<(int * ModuleOrNamespaceRef * ModuleOrNamespaceType) list > - -/// Resolve a long identifier to an object constructor. -val internal ResolveObjectConstructor : NameResolver -> DisplayEnv -> range -> AccessorDomain -> TType -> ResultOrException - -/// Resolve a long identifier using type-qualified name resolution. -val internal ResolveLongIdentInType : TcResultsSink -> NameResolver -> NameResolutionEnv -> LookupKind -> range -> AccessorDomain -> Ident -> FindMemberFlag -> TypeNameResolutionInfo -> TType -> Item * Ident list - -/// Resolve a long identifier when used in a pattern. -val internal ResolvePatternLongIdent : TcResultsSink -> NameResolver -> WarnOnUpperFlag -> bool -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item - -/// Resolve a long identifier representing a type name -val internal ResolveTypeLongIdentInTyconRef : TcResultsSink -> NameResolver -> NameResolutionEnv -> TypeNameResolutionInfo -> AccessorDomain -> range -> ModuleOrNamespaceRef -> Ident list -> TyconRef - -/// Resolve a long identifier to a type definition -val internal ResolveTypeLongIdent : TcResultsSink -> NameResolver -> ItemOccurence -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident list -> TypeNameResolutionStaticArgsInfo -> PermitDirectReferenceToGeneratedType -> ResultOrException - -/// Resolve a long identifier to a field -val internal ResolveField : TcResultsSink -> NameResolver -> NameResolutionEnv -> AccessorDomain -> TType -> Ident list * Ident -> Ident list -> FieldResolution list - -/// Resolve a long identifier occurring in an expression position -val internal ResolveExprLongIdent : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * Ident list - -/// Resolve a (possibly incomplete) long identifier to a loist of possible class or record fields -val internal ResolvePartialLongIdentToClassOrRecdFields : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> bool -> Item list - -/// Return the fields for the given class or record -val internal ResolveRecordOrClassFieldsOfType : NameResolver -> range -> AccessorDomain -> TType -> bool -> Item list - -/// Specifies extra work to do after overload resolution -[] -type AfterResolution = - /// Notification is not needed - | DoNothing - - /// Notify the sink of the information needed to complete recording a use of a symbol - /// for the purposes of the language service. One of the callbacks should be called by - /// the checker. - /// - /// The first callback represents a case where we have learned the type - /// instantiation of a generic method or value. - /// - /// The second represents the case where we have resolved overloading and/or - /// a specific override. The 'Item option' contains the candidate overrides. - | RecordResolution of Item option * (TyparInst -> unit) * (MethInfo * PropInfo option * TyparInst -> unit) * (unit -> unit) - -/// Resolve a long identifier occurring in an expression position. -val internal ResolveLongIdentAsExprAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * range * Ident list * AfterResolution - -/// Resolve a long identifier occurring in an expression position, qualified by a type. -val internal ResolveExprDotLongIdentAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TType -> Ident list -> FindMemberFlag -> bool -> Item * range * Ident list * AfterResolution - -/// A generator of type instantiations used when no more specific type instantiation is known. -val FakeInstantiationGenerator : range -> Typar list -> TType list - -/// Try to resolve a long identifier as type. -val TryToResolveLongIdentAsType : NameResolver -> NameResolutionEnv -> range -> string list -> TType option - -/// Resolve a (possibly incomplete) long identifier to a set of possible resolutions. -val ResolvePartialLongIdent : NameResolver -> NameResolutionEnv -> (MethInfo -> TType -> bool) -> range -> AccessorDomain -> string list -> bool -> Item list - -[] -type ResolveCompletionTargets = - | All of (MethInfo -> TType -> bool) - | SettablePropertiesAndFields - -/// Resolve a (possibly incomplete) long identifier to a set of possible resolutions, qualified by type. -val ResolveCompletionsInType : NameResolver -> NameResolutionEnv -> ResolveCompletionTargets -> Range.range -> AccessorDomain -> bool -> TType -> Item list - -val GetVisibleNamespacesAndModulesAtPoint : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> ModuleOrNamespaceRef list - -val IsItemResolvable : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> Item -> bool +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module internal FSharp.Compiler.NameResolution + +open FSharp.Compiler +open FSharp.Compiler.AccessibilityLogic +open FSharp.Compiler.Ast +open FSharp.Compiler.Infos +open FSharp.Compiler.Range +open FSharp.Compiler.Import +open FSharp.Compiler.InfoReader +open FSharp.Compiler.Tast +open FSharp.Compiler.Tastops +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.AbstractIL.Internal.Library +open FSharp.Compiler.PrettyNaming +open FSharp.Compiler.Text + +/// A NameResolver is a context for name resolution. It primarily holds an InfoReader. +type NameResolver = + new : g:TcGlobals * amap:ImportMap * infoReader:InfoReader * instantiationGenerator:(range -> Typars -> TypeInst) -> NameResolver + member InfoReader : InfoReader + member amap : ImportMap + member g : TcGlobals + +/// Get the active pattern elements defined in a module, if any. Cache in the slot in the module type. +val ActivePatternElemsOfModuleOrNamespace : ModuleOrNamespaceRef -> NameMap + +[] +/// Represents the item with which a named argument is associated. +type ArgumentContainer = + /// The named argument is an argument of a method + | Method of MethInfo + /// The named argument is a static parameter to a provided type or a parameter to an F# exception constructor + | Type of TyconRef + /// The named argument is a static parameter to a union case constructor + | UnionCase of UnionCaseInfo + +//--------------------------------------------------------------------------- +// +//------------------------------------------------------------------------- + +/// Detect a use of a nominal type, including type abbreviations. +/// When reporting symbols, we care about abbreviations, e.g. 'int' and 'int32' count as two separate symbols. +val (|AbbrevOrAppTy|_|) : TType -> TyconRef option + +[] +/// Represents an item that results from name resolution +type Item = + /// Represents the resolution of a name to an F# value or function. + | Value of ValRef + + /// Represents the resolution of a name to an F# union case. + | UnionCase of UnionCaseInfo * bool + + /// Represents the resolution of a name to an F# active pattern result. + | ActivePatternResult of ActivePatternInfo * TType * int * range + + /// Represents the resolution of a name to an F# active pattern case within the body of an active pattern. + | ActivePatternCase of ActivePatternElemRef + + /// Represents the resolution of a name to an F# exception definition. + | ExnCase of TyconRef + + /// Represents the resolution of a name to an F# record field. + | RecdField of RecdFieldInfo + + /// Represents the resolution of a name to a field of an anonymous record type. + | AnonRecdField of AnonRecdTypeInfo * TTypes * int * range + + // The following are never in the items table but are valid results of binding + // an identifier in different circumstances. + + /// Represents the resolution of a name at the point of its own definition. + | NewDef of Ident + + /// Represents the resolution of a name to a .NET field + | ILField of ILFieldInfo + + /// Represents the resolution of a name to an event + | 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 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. + | FakeInterfaceCtor of TType + + /// Represents the resolution of a name to a delegate + | DelegateCtor of TType + + /// Represents the resolution of a name to a group of types + | Types of string * TType list + + /// CustomOperation(nm, helpText, methInfo) + /// + /// Used to indicate the availability or resolution of a custom query operation such as 'sortBy' or 'where' in computation expression syntax + | CustomOperation of string * (unit -> string option) * MethInfo option + + /// Represents the resolution of a name to a custom builder in the F# computation expression syntax + | CustomBuilder of string * ValRef + + /// Represents the resolution of a name to a type variable + | TypeVar of string * Typar + + /// Represents the resolution of a name to a module or namespace + | ModuleOrNamespaces of Tast.ModuleOrNamespaceRef list + + /// Represents the resolution of a name to an operator + | ImplicitOp of Ident * TraitConstraintSln option ref + + /// Represents the resolution of a name to a named argument + | ArgName of Ident * TType * ArgumentContainer option + + /// Represents the resolution of a name to a named property setter + | SetterArg of Ident * Item + + /// Represents the potential resolution of an unqualified name to a type. + | UnqualifiedType of TyconRef list + + member DisplayName : string + +[] +/// Pairs an Item with a TyparInst showing how generic type variables of the item are instantiated at +/// a particular usage point. +type ItemWithInst = + { Item : Item + TyparInst: TyparInst } + +val (|ItemWithInst|) : ItemWithInst -> Item * TyparInst +val ItemWithNoInst : Item -> ItemWithInst + +/// Represents a record field resolution and the information if the usage is deprecated. +type FieldResolution = FieldResolution of RecdFieldRef * bool + +/// Information about an extension member held in the name resolution environment +[] +type ExtensionMember + +/// The environment of information used to resolve names +[] +type NameResolutionEnv = + {eDisplayEnv: DisplayEnv + eUnqualifiedItems: LayeredMap + ePatItems: NameMap + eModulesAndNamespaces: NameMultiMap + eFullyQualifiedModulesAndNamespaces: NameMultiMap + eFieldLabels: NameMultiMap + eTyconsByAccessNames: LayeredMultiMap + eFullyQualifiedTyconsByAccessNames: LayeredMultiMap + eTyconsByDemangledNameAndArity: LayeredMap + eFullyQualifiedTyconsByDemangledNameAndArity: LayeredMap + eIndexedExtensionMembers: TyconRefMultiMap + eUnindexedExtensionMembers: ExtensionMember list + eTypars: NameMap } + static member Empty : g:TcGlobals -> NameResolutionEnv + member DisplayEnv : DisplayEnv + member FindUnqualifiedItem : string -> Item + +type FullyQualifiedFlag = + | FullyQualified + | OpenQualified + +[] +type BulkAdd = Yes | No + +/// Find a field in anonymous record type +val internal TryFindAnonRecdFieldOfType : TcGlobals -> TType -> string -> Item option + +/// Add extra items to the environment for Visual Studio, e.g. static members +val internal AddFakeNamedValRefToNameEnv : string -> NameResolutionEnv -> ValRef -> NameResolutionEnv + +/// Add some extra items to the environment for Visual Studio, e.g. record members +val internal AddFakeNameToNameEnv : string -> NameResolutionEnv -> Item -> NameResolutionEnv + +/// Add a single F# value to the environment. +val internal AddValRefToNameEnv : NameResolutionEnv -> ValRef -> NameResolutionEnv + +/// Add active pattern result tags to the environment. +val internal AddActivePatternResultTagsToNameEnv : ActivePatternInfo -> NameResolutionEnv -> TType -> range -> NameResolutionEnv + +/// Add a list of type definitions to the name resolution environment +val internal AddTyconRefsToNameEnv : BulkAdd -> bool -> TcGlobals -> ImportMap -> range -> bool -> NameResolutionEnv -> TyconRef list -> NameResolutionEnv + +/// Add an F# exception definition to the name resolution environment +val internal AddExceptionDeclsToNameEnv : BulkAdd -> NameResolutionEnv -> TyconRef -> NameResolutionEnv + +/// Add a module abbreviation to the name resolution environment +val internal AddModuleAbbrevToNameEnv : Ident -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv + +/// Add a list of module or namespace to the name resolution environment, including any sub-modules marked 'AutoOpen' +val internal AddModuleOrNamespaceRefsToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv + +/// Add a single modules or namespace to the name resolution environment +val internal AddModuleOrNamespaceRefToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef -> NameResolutionEnv + +/// Add a list of modules or namespaces to the name resolution environment +val internal AddModulesAndNamespacesContentsToNameEnv : TcGlobals -> ImportMap -> AccessorDomain -> range -> bool -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv + +/// A flag which indicates if it is an error to have two declared type parameters with identical names +/// in the name resolution environment. +type CheckForDuplicateTyparFlag = + | CheckForDuplicateTypars + | NoCheckForDuplicateTypars + +/// Add some declared type parameters to the name resolution environment +val internal AddDeclaredTyparsToNameEnv : CheckForDuplicateTyparFlag -> NameResolutionEnv -> Typar list -> NameResolutionEnv + +/// Qualified lookup of type names in the environment +val internal LookupTypeNameInEnvNoArity : FullyQualifiedFlag -> string -> NameResolutionEnv -> TyconRef list + +/// Indicates whether we are resolving type names to type definitions or to constructor methods. +type TypeNameResolutionFlag = + /// Indicates we are resolving type names to constructor methods. + | ResolveTypeNamesToCtors + /// Indicates we are resolving type names to type definitions + | ResolveTypeNamesToTypeRefs + +/// Represents information about the generic argument count of a type name when resolving it. +/// +/// In some situations we resolve "List" to any type definition with that name regardless of the number +/// of generic arguments. In others, we know precisely how many generic arguments are needed. +[] +type TypeNameResolutionStaticArgsInfo = + /// Indicates definite knowledge of empty type arguments, i.e. the logical equivalent of name< > + static member DefiniteEmpty : TypeNameResolutionStaticArgsInfo + /// Deduce definite knowledge of type arguments + static member FromTyArgs : numTyArgs:int -> TypeNameResolutionStaticArgsInfo + +/// Represents information which guides name resolution of types. +[] +type TypeNameResolutionInfo = + | TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo + static member Default : TypeNameResolutionInfo + static member ResolveToTypeRefs : TypeNameResolutionStaticArgsInfo -> TypeNameResolutionInfo + +/// Represents the kind of the occurrence when reporting a name in name resolution +[] +type internal ItemOccurence = + | Binding + | Use + | UseInType + | UseInAttribute + | Pattern + | Implemented + | RelatedText + | Open + +/// Check for equality, up to signature matching +val ItemsAreEffectivelyEqual : TcGlobals -> Item -> Item -> bool + +/// Hash compatible with ItemsAreEffectivelyEqual +val ItemsAreEffectivelyEqualHash : TcGlobals -> Item -> int + +[] +type internal CapturedNameResolution = + /// line and column + member Pos : pos + + /// Named item + member Item : Item + + /// The active instantiation for any generic type parameters + member ItemWithInst: ItemWithInst + + /// Information about the occurrence of the symbol + member ItemOccurence : ItemOccurence + + /// Information about printing. For example, should redundant keywords be hidden? + member DisplayEnv : DisplayEnv + + /// Naming environment--for example, currently open namespaces. + member NameResolutionEnv : NameResolutionEnv + + /// The access rights of code at the location + member AccessorDomain : AccessorDomain + + /// The starting and ending position + member Range : range + +[] +type internal TcResolutions = + + /// Name resolution environments for every interesting region in the file. These regions may + /// overlap, in which case the smallest region applicable should be used. + member CapturedEnvs : ResizeArray + + /// Information of exact types found for expressions, that can be to the left of a dot. + /// typ - the inferred type for an expression + member CapturedExpressionTypings : ResizeArray + + /// Exact name resolutions + member CapturedNameResolutions : ResizeArray + + /// Represents all the resolutions of names to groups of methods. + member CapturedMethodGroupResolutions : ResizeArray + + /// Represents the empty set of resolutions + static member Empty : TcResolutions + + +[] +type TcSymbolUseData = + { Item: Item + ItemOccurence: ItemOccurence + DisplayEnv: DisplayEnv + Range: range } + +[] +/// Represents container for all name resolutions that were met so far when typechecking some particular file +type internal TcSymbolUses = + + /// Get all the uses of a particular item within the file + member GetUsesOfSymbol : Item -> TcSymbolUseData[] + + /// All the uses of all items within the file + member AllUsesOfSymbols : TcSymbolUseData[][] + + /// Get the locations of all the printf format specifiers in the file + member GetFormatSpecifierLocationsAndArity : unit -> (range * int)[] + +/// Represents open declaration statement. +type internal OpenDeclaration = + { /// Long identifier as it's presented in soruce code. + LongId: Ident list + + /// Full range of the open declaration. + Range : range option + + /// Modules or namespaces which is opened with this declaration. + Modules: ModuleOrNamespaceRef list + + /// Scope in which open declaration is visible. + AppliedScope: range + + /// If it's `namespace Xxx.Yyy` declaration. + IsOwnNamespace: bool } + + /// Create a new instance of OpenDeclaration. + static member Create : longId: Ident list * modules: ModuleOrNamespaceRef list * appliedScope: range * isOwnNamespace: bool -> OpenDeclaration + +/// Source text and an array of line end positions, used for format string parsing +type FormatStringCheckContext = + { /// Source text + SourceText: ISourceText + /// Array of line start positions + LineStartPositions: int[] } + +/// An abstract type for reporting the results of name resolution and type checking +type ITypecheckResultsSink = + + /// Record that an environment is active over the given scope range + abstract NotifyEnvWithScope : range * NameResolutionEnv * AccessorDomain -> unit + + /// Record that an expression has a specific type at the given range. + 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 * TyparInst * ItemOccurence * DisplayEnv * NameResolutionEnv * AccessorDomain * range * bool -> unit + + /// Record that a printf format specifier occurred at a specific location in the source + abstract NotifyFormatSpecifierLocation : range * int -> unit + + /// Record that an open declaration occured in a given scope range + abstract NotifyOpenDeclaration : OpenDeclaration -> unit + + /// Get the current source + abstract CurrentSourceText : ISourceText option + + /// Cached line-end normalized source text and an array of line end positions, used for format string parsing + abstract FormatStringCheckContext : FormatStringCheckContext option + +/// An implementation of ITypecheckResultsSink to collect information during type checking +type internal TcResultsSinkImpl = + + /// Create a TcResultsSinkImpl + new : tcGlobals : TcGlobals * ?sourceText: ISourceText -> TcResultsSinkImpl + + /// Get all the resolutions reported to the sink + member GetResolutions : unit -> TcResolutions + + /// Get all the uses of all symbols reported to the sink + member GetSymbolUses : unit -> TcSymbolUses + + /// Get all open declarations reported to the sink + member GetOpenDeclarations : unit -> OpenDeclaration[] + + interface ITypecheckResultsSink + +/// An abstract type for reporting the results of name resolution and type checking, and which allows +/// temporary suspension and/or redirection of reporting. +type TcResultsSink = + { mutable CurrentSink : ITypecheckResultsSink option } + static member NoSink : TcResultsSink + static member WithSink : ITypecheckResultsSink -> TcResultsSink + +/// Temporarily redirect reporting of name resolution and type checking results +val internal WithNewTypecheckResultsSink : ITypecheckResultsSink * TcResultsSink -> System.IDisposable + +/// Temporarily suspend reporting of name resolution and type checking results +val internal TemporarilySuspendReportingTypecheckResultsToSink : TcResultsSink -> System.IDisposable + +/// Report the active name resolution environment for a source range +val internal CallEnvSink : TcResultsSink -> range * NameResolutionEnv * AccessorDomain -> unit + +/// Report a specific name resolution at a source range +val internal CallNameResolutionSink : TcResultsSink -> range * NameResolutionEnv * Item * Item * TyparInst * 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 * TyparInst * ItemOccurence * DisplayEnv * AccessorDomain -> unit + +/// Report a specific name resolution at a source range +val internal CallExprHasTypeSink : TcResultsSink -> range * NameResolutionEnv * TType * DisplayEnv * AccessorDomain -> unit + +/// Report an open declaration +val internal CallOpenDeclarationSink : TcResultsSink -> OpenDeclaration -> unit + +/// Get all the available properties of a type (both intrinsic and extension) +val internal AllPropInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> FindMemberFlag -> range -> TType -> PropInfo list + +/// Get all the available properties of a type (only extension) +val internal ExtensionPropInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> range -> TType -> PropInfo list + +/// Get the available methods of a type (both declared and inherited) +val internal AllMethInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> FindMemberFlag -> range -> TType -> MethInfo list + +/// Used to report an error condition where name resolution failed due to an indeterminate type +exception internal IndeterminateType of range + +/// Used to report a warning condition for the use of upper-case identifiers in patterns +exception internal UpperCaseIdentifierInPattern of range + +/// Generate a new reference to a record field with a fresh type instantiation +val FreshenRecdFieldRef :NameResolver -> Range.range -> Tast.RecdFieldRef -> Item + +/// Indicates the kind of lookup being performed. Note, this type should be made private to nameres.fs. +[] +type LookupKind = + | RecdField + | Pattern + | Expr + | Type + | Ctor + + +/// Indicates if a warning should be given for the use of upper-case identifiers in patterns +type WarnOnUpperFlag = + | WarnOnUpperCase + | AllIdsOK + +/// Indicates whether we permit a direct reference to a type generator. Only set when resolving the +/// right-hand-side of a [] declaration. +[] +type PermitDirectReferenceToGeneratedType = + | Yes + | No + +/// Indicates if we only need one result or all possible results from a resolution. +[] +type ResultCollectionSettings = +| AllResults +| AtMostOneResult + +/// Resolve a long identifier to a namespace or module. +val internal ResolveLongIndentAsModuleOrNamespace : TcResultsSink -> ResultCollectionSettings -> Import.ImportMap -> range -> bool -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident -> Ident list -> isOpenDecl: bool -> ResultOrException<(int * ModuleOrNamespaceRef * ModuleOrNamespaceType) list > + +/// Resolve a long identifier to an object constructor. +val internal ResolveObjectConstructor : NameResolver -> DisplayEnv -> range -> AccessorDomain -> TType -> ResultOrException + +/// Resolve a long identifier using type-qualified name resolution. +val internal ResolveLongIdentInType : TcResultsSink -> NameResolver -> NameResolutionEnv -> LookupKind -> range -> AccessorDomain -> Ident -> FindMemberFlag -> TypeNameResolutionInfo -> TType -> Item * Ident list + +/// Resolve a long identifier when used in a pattern. +val internal ResolvePatternLongIdent : TcResultsSink -> NameResolver -> WarnOnUpperFlag -> bool -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item + +/// Resolve a long identifier representing a type name +val internal ResolveTypeLongIdentInTyconRef : TcResultsSink -> NameResolver -> NameResolutionEnv -> TypeNameResolutionInfo -> AccessorDomain -> range -> ModuleOrNamespaceRef -> Ident list -> TyconRef + +/// Resolve a long identifier to a type definition +val internal ResolveTypeLongIdent : TcResultsSink -> NameResolver -> ItemOccurence -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident list -> TypeNameResolutionStaticArgsInfo -> PermitDirectReferenceToGeneratedType -> ResultOrException + +/// Resolve a long identifier to a field +val internal ResolveField : TcResultsSink -> NameResolver -> NameResolutionEnv -> AccessorDomain -> TType -> Ident list * Ident -> Ident list -> FieldResolution list + +/// Resolve a long identifier occurring in an expression position +val internal ResolveExprLongIdent : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * Ident list + +/// Resolve a (possibly incomplete) long identifier to a loist of possible class or record fields +val internal ResolvePartialLongIdentToClassOrRecdFields : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> bool -> Item list + +/// Return the fields for the given class or record +val internal ResolveRecordOrClassFieldsOfType : NameResolver -> range -> AccessorDomain -> TType -> bool -> Item list + +/// Specifies extra work to do after overload resolution +[] +type AfterResolution = + /// Notification is not needed + | DoNothing + + /// Notify the sink of the information needed to complete recording a use of a symbol + /// for the purposes of the language service. One of the callbacks should be called by + /// the checker. + /// + /// The first callback represents a case where we have learned the type + /// instantiation of a generic method or value. + /// + /// The second represents the case where we have resolved overloading and/or + /// a specific override. The 'Item option' contains the candidate overrides. + | RecordResolution of Item option * (TyparInst -> unit) * (MethInfo * PropInfo option * TyparInst -> unit) * (unit -> unit) + +/// Resolve a long identifier occurring in an expression position. +val internal ResolveLongIdentAsExprAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * range * Ident list * AfterResolution + +/// Resolve a long identifier occurring in an expression position, qualified by a type. +val internal ResolveExprDotLongIdentAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TType -> Ident list -> FindMemberFlag -> bool -> Item * range * Ident list * AfterResolution + +/// A generator of type instantiations used when no more specific type instantiation is known. +val FakeInstantiationGenerator : range -> Typar list -> TType list + +/// Try to resolve a long identifier as type. +val TryToResolveLongIdentAsType : NameResolver -> NameResolutionEnv -> range -> string list -> TType option + +/// Resolve a (possibly incomplete) long identifier to a set of possible resolutions. +val ResolvePartialLongIdent : NameResolver -> NameResolutionEnv -> (MethInfo -> TType -> bool) -> range -> AccessorDomain -> string list -> bool -> Item list + +[] +type ResolveCompletionTargets = + | All of (MethInfo -> TType -> bool) + | SettablePropertiesAndFields + +/// Resolve a (possibly incomplete) long identifier to a set of possible resolutions, qualified by type. +val ResolveCompletionsInType : NameResolver -> NameResolutionEnv -> ResolveCompletionTargets -> Range.range -> AccessorDomain -> bool -> TType -> Item list + +val GetVisibleNamespacesAndModulesAtPoint : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> ModuleOrNamespaceRef list + +val IsItemResolvable : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> Item -> bool diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 9a3018d096c..cf6f1991c69 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -148,8 +148,8 @@ type InProcErrorLoggerProvider() = CollectDiagnostic (tcConfigBuilder.implicitIncludeDir, tcConfigBuilder.showFullPaths, tcConfigBuilder.flatErrors, tcConfigBuilder.errorStyle, isError, err, true) - let container = if isError then errors else warnings - container.AddRange(errs) } + let container = if isError then errors else warnings + container.AddRange(errs) } :> ErrorLogger } member __.CapturedErrors = errors.ToArray() diff --git a/src/fsharp/fsi/fsi.fsproj b/src/fsharp/fsi/fsi.fsproj index a7bafddfded..94c2e5a4013 100644 --- a/src/fsharp/fsi/fsi.fsproj +++ b/src/fsharp/fsi/fsi.fsproj @@ -30,6 +30,9 @@ + + + diff --git a/src/utils/prim-lexing.fs b/src/utils/prim-lexing.fs index cfac1ee7d4f..c397257b46c 100644 --- a/src/utils/prim-lexing.fs +++ b/src/utils/prim-lexing.fs @@ -103,8 +103,8 @@ module SourceText = namespace Internal.Utilities.Text.Lexing - open Microsoft.FSharp.Core open FSharp.Compiler.Text + open Microsoft.FSharp.Core open Microsoft.FSharp.Collections open System.Collections.Generic diff --git a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs index 426236543f7..da7ae84baf2 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs @@ -73,6 +73,33 @@ type internal FSharpCheckerWorkspaceServiceFactory member this.Checker = checkerProvider.Checker member this.FSharpProjectOptionsManager = projectInfoManager } +[] +type private FSharpSolutionEvents(projectManager: FSharpProjectOptionsManager) = + + interface IVsSolutionEvents with + + member __.OnAfterCloseSolution(_) = + projectManager.Checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() + VSConstants.S_OK + + member __.OnAfterLoadProject(_, _) = VSConstants.E_NOTIMPL + + member __.OnAfterOpenProject(_, _) = VSConstants.E_NOTIMPL + + member __.OnAfterOpenSolution(_, _) = VSConstants.E_NOTIMPL + + member __.OnBeforeCloseProject(_, _) = VSConstants.E_NOTIMPL + + member __.OnBeforeCloseSolution(_) = VSConstants.E_NOTIMPL + + member __.OnBeforeUnloadProject(_, _) = VSConstants.E_NOTIMPL + + member __.OnQueryCloseProject(_, _, _) = VSConstants.E_NOTIMPL + + member __.OnQueryCloseSolution(_, _) = VSConstants.E_NOTIMPL + + member __.OnQueryUnloadProject(_, _) = VSConstants.E_NOTIMPL + [, Microsoft.CodeAnalysis.Host.Mef.ServiceLayer.Default)>] type internal FSharpSettingsFactory [] (settings: EditorOptions) = @@ -143,6 +170,8 @@ type internal FSharpPackage() as this = vfsiToolWindow <- this.FindToolWindow(typeof, 0, true) :?> Microsoft.VisualStudio.FSharp.Interactive.FsiToolWindow vfsiToolWindow :> Microsoft.VisualStudio.FSharp.Interactive.ITestVFSI + let mutable solutionEventsOpt = None + // FSI-LINKAGE-POINT: unsited init do Microsoft.VisualStudio.FSharp.Interactive.Hooks.fsiConsoleWindowPackageCtorUnsited (this :> Package) @@ -165,9 +194,13 @@ type internal FSharpPackage() as this = let projectInfoManager = this.ComponentModel.DefaultExportProvider.GetExport().Value let solution = this.GetServiceAsync(typeof).Result let solution = solution :?> IVsSolution + let solutionEvents = FSharpSolutionEvents(projectInfoManager) let rdt = this.GetServiceAsync(typeof).Result let rdt = rdt :?> IVsRunningDocumentTable + solutionEventsOpt <- Some(solutionEvents) + solution.AdviseSolutionEvents(solutionEvents) |> ignore + let projectContextFactory = this.ComponentModel.GetService() let workspace = this.ComponentModel.GetService() let miscFilesWorkspace = this.ComponentModel.GetService() diff --git a/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj b/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj index c317a7a2e72..8810e56d674 100644 --- a/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj +++ b/vsintegration/tests/UnitTests/VisualFSharp.UnitTests.fsproj @@ -165,6 +165,8 @@ Roslyn\DocumentHighlightsServiceTests.fs + + PreserveNewest