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

Finish adding signature files to src/fsharp #10692

Merged
merged 8 commits into from
Dec 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/fsharp/AccessibilityLogic.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ open FSharp.Compiler.ExtensionTyping
/// Represents the 'keys' a particular piece of code can use to access other constructs?.
[<NoEquality; NoComparison>]
type AccessorDomain =
/// AccessibleFrom(cpaths, tyconRefOpt)
///
/// cpaths: indicates we have the keys to access any members private to the given paths
/// tyconRefOpt: indicates we have the keys to access any protected members of the super types of 'TyconRef'
| AccessibleFrom of CompilationPath list * TyconRef option
| AccessibleFrom of cpaths: CompilationPath list * tyconRefOpt: TyconRef option

/// An AccessorDomain which returns public items
| AccessibleFromEverywhere
Expand All @@ -46,6 +44,7 @@ type AccessorDomain =
| AccessibleFromEverywhere -> 2
| AccessibleFromSomeFSharpCode -> 3
| AccessibleFromSomewhere -> 4

static member CustomEquals(g:TcGlobals, ad1:AccessorDomain, ad2:AccessorDomain) =
match ad1, ad2 with
| AccessibleFrom(cs1, tc1), AccessibleFrom(cs2, tc2) -> (cs1 = cs2) && (match tc1, tc2 with None, None -> true | Some tc1, Some tc2 -> tyconRefEq g tc1 tc2 | _ -> false)
Expand Down Expand Up @@ -224,7 +223,6 @@ let ComputeILAccess isPublic isFamily isFamilyOrAssembly isFamilyAndAssembly =
elif isFamilyAndAssembly then ILMemberAccess.FamilyAndAssembly
else ILMemberAccess.Private

/// IndiCompute the accessibility of a provided member
let IsILFieldInfoAccessible g amap m ad x =
match x with
| ILFieldInfo (tinfo, fd) -> IsILTypeAndMemberAccessible g amap m ad ad tinfo fd.Access
Expand Down
100 changes: 100 additions & 0 deletions src/fsharp/AccessibilityLogic.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

/// The basic logic of private/internal/protected/InternalsVisibleTo/public accessibility
module internal FSharp.Compiler.AccessibilityLogic

open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler
open FSharp.Compiler.Import
open FSharp.Compiler.Infos
open FSharp.Compiler.TypedTree
open FSharp.Compiler.Range
open FSharp.Compiler.TcGlobals

/// Represents the 'keys' a particular piece of code can use to access other constructs?.
[<NoEquality; NoComparison>]
type AccessorDomain =
/// cpaths: indicates we have the keys to access any members private to the given paths
/// tyconRefOpt: indicates we have the keys to access any protected members of the super types of 'TyconRef'
| AccessibleFrom of cpaths: CompilationPath list * tyconRefOpt: TyconRef option

/// An AccessorDomain which returns public items
| AccessibleFromEverywhere

/// An AccessorDomain which returns everything but .NET private/internal items.
/// This is used
/// - when solving member trait constraints, which are solved independently of accessibility
/// - for failure paths in error reporting, e.g. to produce an error that an F# item is not accessible
/// - an adhoc use in service.fs to look up a delegate signature
| AccessibleFromSomeFSharpCode

/// An AccessorDomain which returns all items
| AccessibleFromSomewhere

// Hashing and comparison is used for the memoization tables keyed by an accessor domain.
// It is dependent on a TcGlobals because of the TyconRef in the data structure
static member CustomEquals: g:TcGlobals * ad1:AccessorDomain * ad2:AccessorDomain -> bool

// Hashing and comparison is used for the memoization tables keyed by an accessor domain.
// It is dependent on a TcGlobals because of the TyconRef in the data structure
static member CustomGetHashCode: ad:AccessorDomain -> int

/// Indicates if an F# item is accessible
val IsAccessible: ad:AccessorDomain -> taccess:TypedTree.Accessibility -> bool

/// Indicates if an entity is accessible
val IsEntityAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TypedTree.TyconRef -> bool

/// Check that an entity is accessible
val CheckTyconAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TypedTree.TyconRef -> bool

/// Indicates if a type definition and its representation contents are accessible
val IsTyconReprAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TypedTree.TyconRef -> bool

/// Check that a type definition and its representation contents are accessible
val CheckTyconReprAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> tcref:TypedTree.TyconRef -> bool

/// Indicates if a type is accessible (both definition and instantiation)
val IsTypeAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> ty:TypedTree.TType -> bool

val IsTypeInstAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> tinst:TypedTree.TypeInst -> bool

/// Indicate if a provided member is accessible
val IsProvidedMemberAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> ty:TypedTree.TType -> access:ILMemberAccess -> bool

/// Compute the accessibility of a provided member
val ComputeILAccess: isPublic:bool -> isFamily:bool -> isFamilyOrAssembly:bool -> isFamilyAndAssembly:bool -> ILMemberAccess

val IsILFieldInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> x:ILFieldInfo -> bool

val GetILAccessOfILEventInfo: ILEventInfo -> ILMemberAccess

val IsILEventInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> einfo:ILEventInfo -> bool

val GetILAccessOfILPropInfo: ILPropInfo -> ILMemberAccess

val IsILPropInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> pinfo:ILPropInfo -> bool

val IsValAccessible: ad:AccessorDomain -> vref:TypedTree.ValRef -> bool

val CheckValAccessible: m:range -> ad:AccessorDomain -> vref:TypedTree.ValRef -> unit

val IsUnionCaseAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> ucref:TypedTree.UnionCaseRef -> bool

val CheckUnionCaseAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> ucref:TypedTree.UnionCaseRef -> bool

val IsRecdFieldAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> rfref:TypedTree.RecdFieldRef -> bool

val CheckRecdFieldAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> rfref:TypedTree.RecdFieldRef -> bool

val CheckRecdFieldInfoAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> rfinfo:RecdFieldInfo -> unit

val CheckILFieldInfoAccessible: g:TcGlobals -> amap:ImportMap -> m:range -> ad:AccessorDomain -> finfo:ILFieldInfo -> unit

val IsTypeAndMethInfoAccessible: amap:ImportMap -> m:range -> accessDomainTy:AccessorDomain -> ad:AccessorDomain -> _arg1:MethInfo -> bool

val IsMethInfoAccessible: amap:ImportMap -> m:range -> ad:AccessorDomain -> minfo:MethInfo -> bool

val IsPropInfoAccessible: g:TcGlobals ->amap:ImportMap -> m:range -> ad:AccessorDomain -> _arg1:PropInfo -> bool

val IsFieldInfoAccessible: ad:AccessorDomain -> rfref:RecdFieldInfo -> bool
32 changes: 4 additions & 28 deletions src/fsharp/AttributeChecking.fs
Original file line number Diff line number Diff line change
Expand Up @@ -179,29 +179,6 @@ let GetAttribInfosOfEvent amap m einfo =
| ProvidedEvent _ -> []
#endif

/// Analyze three cases for attributes declared on type definitions: IL-declared attributes, F#-declared attributes and
/// provided attributes.
//
// This is used for AttributeUsageAttribute, DefaultMemberAttribute and ConditionalAttribute (on attribute types)
let TryBindTyconRefAttribute g m (AttribInfo (atref, _) as args) (tcref:TyconRef) f1 f2 f3 =
ignore m; ignore f3
match metadataOfTycon tcref.Deref with
#if !NO_EXTENSIONTYPING
| ProvidedTypeMetadata info ->
let provAttribs = info.ProvidedType.PApply((fun a -> (a :> IProvidedCustomAttributeProvider)), m)
match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), atref.FullName)), m) with
| Some args -> f3 args
| None -> None
#endif
| ILTypeMetadata (TILObjectReprData(_, _, tdef)) ->
match TryDecodeILAttribute g atref tdef.CustomAttrs with
| Some attr -> f1 attr
| _ -> None
| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
match TryFindFSharpAttribute g args tcref.Attribs with
| Some attr -> f2 attr
| _ -> None

/// Analyze three cases for attributes declared on methods: IL-declared attributes, F#-declared attributes and
/// provided attributes.
let BindMethInfoAttributes m minfo f1 f2 f3 =
Expand All @@ -216,9 +193,8 @@ let BindMethInfoAttributes m minfo f1 f2 f3 =

/// Analyze three cases for attributes declared on methods: IL-declared attributes, F#-declared attributes and
/// provided attributes.
let TryBindMethInfoAttribute g m (AttribInfo(atref, _) as attribSpec) minfo f1 f2 f3 =
#if !NO_EXTENSIONTYPING
#else
let TryBindMethInfoAttribute g (m: range) (AttribInfo(atref, _) as attribSpec) minfo f1 f2 f3 =
#if NO_EXTENSIONTYPING
// to prevent unused parameter warning
ignore f3
#endif
Expand All @@ -237,7 +213,7 @@ let TryBindMethInfoAttribute g m (AttribInfo(atref, _) as attribSpec) minfo f1 f
/// Try to find a specific attribute on a method, where the attribute accepts a string argument.
///
/// This is just used for the 'ConditionalAttribute' attribute
let TryFindMethInfoStringAttribute g m attribSpec minfo =
let TryFindMethInfoStringAttribute g (m: range) attribSpec minfo =
TryBindMethInfoAttribute g m attribSpec minfo
(function ([ILAttribElem.String (Some msg) ], _) -> Some msg | _ -> None)
(function (Attrib(_, _, [ AttribStringArg msg ], _, _, _, _)) -> Some msg | _ -> None)
Expand Down Expand Up @@ -438,7 +414,7 @@ let CheckMethInfoAttributes g m tyargsOpt minfo =

/// Indicate if a method has 'Obsolete', 'CompilerMessageAttribute' or 'TypeProviderEditorHideMethodsAttribute'.
/// Used to suppress the item in intellisense.
let MethInfoIsUnseen g m ty minfo =
let MethInfoIsUnseen g (m: range) (ty: TType) minfo =
let isUnseenByObsoleteAttrib () =
match BindMethInfoAttributes m minfo
(fun ilAttribs -> Some(CheckILAttributesForUnseen g ilAttribs m))
Expand Down
80 changes: 80 additions & 0 deletions src/fsharp/AttributeChecking.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

/// Logic associated with checking "ObsoleteAttribute" and other attributes
/// on items from name resolution
module internal FSharp.Compiler.AttributeChecking

open System.Collections.Generic
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Infos
open FSharp.Compiler.Range
open FSharp.Compiler.TypedTree
open FSharp.Compiler.TcGlobals

exception ObsoleteWarning of string * range
exception ObsoleteError of string * range

type AttribInfo =
| FSAttribInfo of TcGlobals * Attrib
| ILAttribInfo of TcGlobals * Import.ImportMap * ILScopeRef * ILAttribute * range
member ConstructorArguments: (TType * obj) list
member NamedArguments: (TType * string * bool * obj) list
member Range: range
member TyconRef: TyconRef

val AttribInfosOfIL: g:TcGlobals -> amap:Import.ImportMap -> scoref:ILScopeRef -> m:range -> attribs:ILAttributes -> AttribInfo list

val GetAttribInfosOfEntity: g:TcGlobals -> amap:Import.ImportMap -> m:range -> tcref:TyconRef -> AttribInfo list

val GetAttribInfosOfMethod: amap:Import.ImportMap -> m:range -> minfo:MethInfo -> AttribInfo list

val GetAttribInfosOfProp: amap:Import.ImportMap -> m:range -> pinfo:PropInfo -> AttribInfo list

val GetAttribInfosOfEvent: amap:Import.ImportMap -> m:range -> einfo:EventInfo -> AttribInfo list

#if NO_EXTENSIONTYPING
val TryBindMethInfoAttribute: g:TcGlobals -> m:range -> BuiltinAttribInfo -> minfo:MethInfo -> f1:(ILAttribElem list * ILAttributeNamedArg list -> 'a option) -> f2:(Attrib -> 'a option) -> f3: _ -> 'a option
#else
val TryBindMethInfoAttribute: g:TcGlobals -> m:range -> BuiltinAttribInfo -> minfo:MethInfo -> f1:(ILAttribElem list * ILAttributeNamedArg list -> 'a option) -> f2:(Attrib -> 'a option) -> f3:(obj option list * (string * obj option) list -> 'a option) -> 'a option
#endif

val TryFindMethInfoStringAttribute: g:TcGlobals -> m:range -> attribSpec:BuiltinAttribInfo -> minfo:MethInfo -> string option

val MethInfoHasAttribute: g:TcGlobals -> m:range -> attribSpec:BuiltinAttribInfo -> minfo:MethInfo -> bool

val CheckFSharpAttributes: g:TcGlobals -> attribs:Attrib list -> m:range -> OperationResult<unit>

val CheckILAttributesForUnseen: g:TcGlobals -> cattrs:ILAttributes -> _m:'a -> bool

val CheckFSharpAttributesForHidden: g:TcGlobals -> attribs:Attrib list -> bool

val CheckFSharpAttributesForObsolete: g:TcGlobals -> attribs:Attrib list -> bool

val CheckFSharpAttributesForUnseen: g:TcGlobals -> attribs:Attrib list -> _m:'a -> bool

val CheckPropInfoAttributes: pinfo:PropInfo -> m:range -> OperationResult<unit>

val CheckILFieldAttributes: g:TcGlobals -> finfo:ILFieldInfo -> m:range -> unit

val CheckMethInfoAttributes: g:TcGlobals -> m:range -> tyargsOpt:'a option -> minfo:MethInfo -> OperationResult<unit>

val MethInfoIsUnseen: g:TcGlobals -> m:range -> ty:TType -> minfo:MethInfo -> bool

val PropInfoIsUnseen: m:'a -> pinfo:PropInfo -> bool

val CheckEntityAttributes: g:TcGlobals -> x:TyconRef -> m:range -> OperationResult<unit>

val CheckUnionCaseAttributes: g:TcGlobals -> x:UnionCaseRef -> m:range -> OperationResult<unit>

val CheckRecdFieldAttributes: g:TcGlobals -> x:RecdFieldRef -> m:range -> OperationResult<unit>

val CheckValAttributes: g:TcGlobals -> x:ValRef -> m:range -> OperationResult<unit>

val CheckRecdFieldInfoAttributes: g:TcGlobals -> x:RecdFieldInfo -> m:range -> OperationResult<unit>

val IsSecurityAttribute: g:TcGlobals -> amap:Import.ImportMap -> casmap:Dictionary<Stamp,bool> -> Attrib -> m:range -> bool

val IsSecurityCriticalAttribute: g:TcGlobals -> Attrib -> bool

5 changes: 0 additions & 5 deletions src/fsharp/CompilerGlobalState.fs
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,12 @@ type StableNiceNameGenerator() =

type internal CompilerGlobalState () =
/// A global generator of compiler generated names
// ++GLOBAL MUTABLE STATE (concurrency safe by locking inside NiceNameGenerator)
let globalNng = NiceNameGenerator()


/// A global generator of stable compiler generated names
// MUTABLE STATE (concurrency safe by locking inside StableNiceNameGenerator)
let globalStableNameGenerator = StableNiceNameGenerator ()

/// A name generator used by IlxGen for static fields, some generated arguments and other things.
/// REVIEW: this will mean the hosted compiler service is not deterministic. We should at least create a new one
/// of these for each compilation.
let ilxgenGlobalNng = NiceNameGenerator ()

member __.NiceNameGenerator = globalNng
Expand Down
54 changes: 54 additions & 0 deletions src/fsharp/CompilerGlobalState.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

/// Defines the global environment for all type checking.

module FSharp.Compiler.CompilerGlobalState

open FSharp.Compiler.Range

/// Generates compiler-generated names. Each name generated also includes the StartLine number of the range passed in
/// at the point of first generation.
///
/// This type may be accessed concurrently, though in practice it is only used from the compilation thread.
/// It is made concurrency-safe since a global instance of the type is allocated in tast.fs, and it is good
/// policy to make all globally-allocated objects concurrency safe in case future versions of the compiler
/// are used to host multiple concurrent instances of compilation.
type NiceNameGenerator =

new: unit -> NiceNameGenerator
member FreshCompilerGeneratedName: name:string * m:range -> string
member Reset: unit -> unit

/// Generates compiler-generated names marked up with a source code location, but if given the same unique value then
/// return precisely the same name. Each name generated also includes the StartLine number of the range passed in
/// at the point of first generation.
///
/// This type may be accessed concurrently, though in practice it is only used from the compilation thread.
/// It is made concurrency-safe since a global instance of the type is allocated in tast.fs.
type StableNiceNameGenerator =

new: unit -> StableNiceNameGenerator
member GetUniqueCompilerGeneratedName: name:string * m:range * uniq:int64 -> string
member Reset: unit -> unit

type internal CompilerGlobalState =

new: unit -> CompilerGlobalState

/// A name generator used by IlxGen for static fields, some generated arguments and other things.
member IlxGenNiceNameGenerator: NiceNameGenerator

/// A global generator of compiler generated names
member NiceNameGenerator: NiceNameGenerator

/// A global generator of stable compiler generated names
member StableNameGenerator: StableNiceNameGenerator

type Unique = int64

/// Concurrency-safe
val newUnique: (unit -> int64)

/// Unique name generator for stamps attached to to val_specs, tycon_specs etc.
/// Concurrency-safe
val newStamp: (unit -> int64)
17 changes: 7 additions & 10 deletions src/fsharp/CompilerImports.fs
Original file line number Diff line number Diff line change
Expand Up @@ -692,12 +692,7 @@ type RawFSharpAssemblyDataBackedByFileOnDisk (ilModule: ILModuleDef, ilAssemblyR
//--------------------------------------------------------------------------

[<Sealed>]
type TcImportsSafeDisposal
(disposeActions: ResizeArray<unit -> unit>,
#if !NO_EXTENSIONTYPING
disposeTypeProviderActions: ResizeArray<unit -> unit>
#endif
) =
type TcImportsSafeDisposal(disposeActions: ResizeArray<unit -> unit>,disposeTypeProviderActions: ResizeArray<unit -> unit>) =

let mutable isDisposed = false

Expand All @@ -706,9 +701,7 @@ type TcImportsSafeDisposal
isDisposed <- true
if verbose then
dprintf "disposing of TcImports, %d binaries\n" disposeActions.Count
#if !NO_EXTENSIONTYPING
for action in disposeTypeProviderActions do action()
#endif
for action in disposeActions do action()

override _.Finalize() =
Expand Down Expand Up @@ -758,7 +751,11 @@ and TcImportsWeakHack (tcImports: WeakReference<TcImports>) =
/// Is a disposable object, but it is recommended not to explicitly call Dispose unless you absolutely know nothing will be using its contents after the disposal.
/// Otherwise, simply allow the GC to collect this and it will properly call Dispose from the finalizer.
and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolutions, importsBase: TcImports option,
ilGlobalsOpt, dependencyProviderOpt: DependencyProvider option) as this =
ilGlobalsOpt, dependencyProviderOpt: DependencyProvider option)
#if !NO_EXTENSIONTYPING
as this
#endif
=

let mutable resolutions = initialResolutions
let mutable importsBase: TcImports option = importsBase
Expand All @@ -777,8 +774,8 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse
let mutable disposed = false
let mutable ilGlobalsOpt = ilGlobalsOpt
let mutable tcGlobals = None
#if !NO_EXTENSIONTYPING
let disposeTypeProviderActions = ResizeArray()
#if !NO_EXTENSIONTYPING
let mutable generatedTypeRoots = new System.Collections.Generic.Dictionary<ILTypeRef, int * ProviderGeneratedType>()
let mutable tcImportsWeak = TcImportsWeakHack (WeakReference<_> this)
#endif
Expand Down
Loading