Skip to content

Commit eae91ea

Browse files
committed
Merge pull request #418 from Jand42/master
Exposing assembly attributes on FSharpAssemblySignature
2 parents 222a5df + da3fb4f commit eae91ea

File tree

7 files changed

+41
-20
lines changed

7 files changed

+41
-20
lines changed

src/fsharp/fsi/fsi.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ type internal FsiDynamicCompiler
12521252
}
12531253

12541254
member __.CurrentPartialAssemblySignature(istate) =
1255-
FSharpAssemblySignature(istate.tcGlobals, istate.tcState.Ccu, istate.tcImports, istate.tcState.PartialAssemblySignature)
1255+
FSharpAssemblySignature(istate.tcGlobals, istate.tcState.Ccu, istate.tcImports, None, istate.tcState.PartialAssemblySignature)
12561256

12571257

12581258
//----------------------------------------------------------------------------

src/fsharp/vs/IncrementalBuild.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,7 @@ module internal IncrementalFSharpBuild =
11721172
Errors : (PhasedError * FSharpErrorSeverity) list
11731173
TcResolutions: TcResolutions list
11741174
TcSymbolUses: TcSymbolUses list
1175+
TopAttribs: TopAttribs option
11751176
TimeStamp: System.DateTime }
11761177

11771178
let GetPartialCheckResults (tcAcc: TypeCheckAccumulator, timestamp) =
@@ -1183,6 +1184,7 @@ module internal IncrementalFSharpBuild =
11831184
Errors = tcAcc.tcErrors
11841185
TcResolutions = tcAcc.tcResolutions
11851186
TcSymbolUses = tcAcc.tcSymbolUses
1187+
TopAttribs = tcAcc.topAttribs
11861188
TimeStamp = timestamp }
11871189

11881190

src/fsharp/vs/IncrementalBuild.fsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ module internal IncrementalFSharpBuild =
6161
Errors : (PhasedError * FSharpErrorSeverity) list
6262
TcResolutions: TcResolutions list
6363
TcSymbolUses: TcSymbolUses list
64+
TopAttribs: TypeChecker.TopAttribs option
6465
TimeStamp: DateTime }
6566

6667
[<Class>]

src/fsharp/vs/Symbols.fs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,9 +1813,9 @@ and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayA
18131813
override x.ToString() =
18141814
"parameter " + (match x.Name with None -> "<unnamed" | Some s -> s)
18151815

1816-
and FSharpAssemblySignature internal (cenv, mtyp: ModuleOrNamespaceType) =
1816+
and FSharpAssemblySignature internal (cenv, topAttribs: TypeChecker.TopAttribs option, mtyp: ModuleOrNamespaceType) =
18171817

1818-
new (g, thisCcu, tcImports, mtyp) = FSharpAssemblySignature(cenv(g,thisCcu,tcImports), mtyp)
1818+
new (g, thisCcu, tcImports, topAttribs, mtyp) = FSharpAssemblySignature(cenv(g,thisCcu,tcImports), topAttribs, mtyp)
18191819

18201820
member __.Entities =
18211821

@@ -1828,6 +1828,13 @@ and FSharpAssemblySignature internal (cenv, mtyp: ModuleOrNamespaceType) =
18281828

18291829
loop mtyp |> makeReadOnlyCollection
18301830

1831+
member __.Attributes =
1832+
match topAttribs with
1833+
| None -> makeReadOnlyCollection []
1834+
| Some tA ->
1835+
tA.assemblyAttrs
1836+
|> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a))) |> makeReadOnlyCollection
1837+
18311838
override x.ToString() = "<assembly signature>"
18321839

18331840
and FSharpAssembly internal (cenv, ccu: CcuThunk) =
@@ -1840,7 +1847,7 @@ and FSharpAssembly internal (cenv, ccu: CcuThunk) =
18401847
member __.FileName = ccu.FileName
18411848
member __.SimpleName = ccu.AssemblyName
18421849
member __.IsProviderGenerated = ccu.IsProviderGenerated
1843-
member __.Contents = FSharpAssemblySignature((if ccu.IsUnresolvedReference then cenv else (new cenv(cenv.g, ccu, cenv.tcImports))), ccu.Contents.ModuleOrNamespaceType)
1850+
member __.Contents = FSharpAssemblySignature((if ccu.IsUnresolvedReference then cenv else (new cenv(cenv.g, ccu, cenv.tcImports))), None, ccu.Contents.ModuleOrNamespaceType)
18441851

18451852
override x.ToString() = x.QualifiedName
18461853

src/fsharp/vs/Symbols.fsi

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,16 @@ and [<Class>] FSharpAssembly =
104104
/// Represents an inferred signature of part of an assembly as seen by the F# language
105105
and [<Class>] FSharpAssemblySignature =
106106

107-
internal new : tcGlobals: TcGlobals * thisCcu: CcuThunk * tcImports: TcImports * contents: ModuleOrNamespaceType -> FSharpAssemblySignature
107+
internal new : tcGlobals: TcGlobals * thisCcu: CcuThunk * tcImports: TcImports * topAttribs: TypeChecker.TopAttribs option * contents: ModuleOrNamespaceType -> FSharpAssemblySignature
108108

109109
/// The (non-nested) module and type definitions in this signature
110110
member Entities: IList<FSharpEntity>
111111

112+
/// Get the declared attributes for the assembly.
113+
/// Only available when parsing an entire project.
114+
member Attributes: IList<FSharpAttribute>
115+
116+
112117
/// A subtype of FSharpSymbol that represents a type definition or module as seen by the F# language
113118
and [<Class>] FSharpEntity =
114119
inherit FSharpSymbol

src/fsharp/vs/service.fs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,7 +1467,7 @@ type TypeCheckInfo
14671467
let symbol = FSharpSymbol.Create(g, thisCcu, tcImports, item)
14681468
Some (symbol, denv, m)
14691469

1470-
member scope.PartialAssemblySignature() = FSharpAssemblySignature(g, thisCcu, tcImports, ccuSig)
1470+
member scope.PartialAssemblySignature() = FSharpAssemblySignature(g, thisCcu, tcImports, None, ccuSig)
14711471

14721472
member scope.AccessRights = tcAccessRights
14731473

@@ -1880,7 +1880,7 @@ type FSharpProjectContext(thisCcu: CcuThunk, assemblies: FSharpAssembly list, ad
18801880

18811881
[<Sealed>]
18821882
// 'details' is an option because the creation of the tcGlobals etc. for the project may have failed.
1883-
type FSharpCheckProjectResults(keepAssemblyContents, errors: FSharpErrorInfo[], details:(TcGlobals*TcImports*CcuThunk*ModuleOrNamespaceType*TcSymbolUses list*CompileOps.IRawFSharpAssemblyData option * ILAssemblyRef * AccessorDomain * TypedAssembly option) option, reactorOps: IReactorOperations) =
1883+
type FSharpCheckProjectResults(keepAssemblyContents, errors: FSharpErrorInfo[], details:(TcGlobals*TcImports*CcuThunk*ModuleOrNamespaceType*TcSymbolUses list*TopAttribs option*CompileOps.IRawFSharpAssemblyData option * ILAssemblyRef * AccessorDomain * TypedAssembly option) option, reactorOps: IReactorOperations) =
18841884

18851885
let getDetails() =
18861886
match details with
@@ -1892,12 +1892,12 @@ type FSharpCheckProjectResults(keepAssemblyContents, errors: FSharpErrorInfo[],
18921892
member info.HasCriticalErrors = details.IsNone
18931893

18941894
member info.AssemblySignature =
1895-
let (tcGlobals, tcImports, thisCcu, ccuSig, _tcSymbolUses, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
1896-
FSharpAssemblySignature(tcGlobals, thisCcu, tcImports, ccuSig)
1895+
let (tcGlobals, tcImports, thisCcu, ccuSig, _tcSymbolUses, topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
1896+
FSharpAssemblySignature(tcGlobals, thisCcu, tcImports, topAttribs, ccuSig)
18971897

18981898
member info.AssemblyContents =
18991899
if not keepAssemblyContents then invalidOp "The 'keepAssemblyContents' flag must be set to tru on the FSharpChecker in order to access the checked contents of assemblies"
1900-
let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr) = getDetails()
1900+
let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, tcAssemblyExpr) = getDetails()
19011901
let mimpls =
19021902
match tcAssemblyExpr with
19031903
| None -> []
@@ -1906,7 +1906,7 @@ type FSharpCheckProjectResults(keepAssemblyContents, errors: FSharpErrorInfo[],
19061906

19071907
// Not, this does not have to be a SyncOp, it can be called from any thread
19081908
member info.GetUsesOfSymbol(symbol:FSharpSymbol) =
1909-
let (tcGlobals, _tcImports, _thisCcu, _ccuSig, tcSymbolUses, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
1909+
let (tcGlobals, _tcImports, _thisCcu, _ccuSig, tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
19101910
// This probably doesn't need to be run on the reactor since all data touched by GetUsesOfSymbol is immutable.
19111911
reactorOps.EnqueueAndAwaitOpAsync(fun () ->
19121912
[| for r in tcSymbolUses do yield! r.GetUsesOfSymbol(symbol.Item) |]
@@ -1916,7 +1916,7 @@ type FSharpCheckProjectResults(keepAssemblyContents, errors: FSharpErrorInfo[],
19161916

19171917
// Not, this does not have to be a SyncOp, it can be called from any thread
19181918
member info.GetAllUsesOfAllSymbols() =
1919-
let (tcGlobals, tcImports, thisCcu, _ccuSig, tcSymbolUses, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
1919+
let (tcGlobals, tcImports, thisCcu, _ccuSig, tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
19201920
// This probably doesn't need to be run on the reactor since all data touched by GetAllUsesOfSymbols is immutable.
19211921
reactorOps.EnqueueAndAwaitOpAsync(fun () ->
19221922
[| for r in tcSymbolUses do
@@ -1925,18 +1925,18 @@ type FSharpCheckProjectResults(keepAssemblyContents, errors: FSharpErrorInfo[],
19251925
yield FSharpSymbolUse(tcGlobals, denv, symbol, itemOcc, m) |])
19261926

19271927
member info.ProjectContext =
1928-
let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _tcAssemblyData, _ilAssemRef, ad, _tcAssemblyExpr) = getDetails()
1928+
let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, ad, _tcAssemblyExpr) = getDetails()
19291929
let assemblies =
1930-
[ for x in tcImports.GetImportedAssemblies() do
1930+
[ for x in tcImports.GetImportedAssemblies() do
19311931
yield FSharpAssembly(tcGlobals, thisCcu, tcImports, x.FSharpViewOfMetadata) ]
19321932
FSharpProjectContext(thisCcu, assemblies, ad)
19331933

19341934
member info.RawFSharpAssemblyData =
1935-
let (_tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
1935+
let (_tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, tcAssemblyData, _ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
19361936
tcAssemblyData
19371937

19381938
member info.AssemblyFullName =
1939-
let (_tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _tcAssemblyData, ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
1939+
let (_tcGlobals, _tcImports, _thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, ilAssemRef, _ad, _tcAssemblyExpr) = getDetails()
19401940
ilAssemRef.QualifiedName
19411941

19421942
[<Sealed>]
@@ -2419,7 +2419,7 @@ type BackgroundCompiler(projectCacheSize, keepAssemblyContents, keepAllBackgroun
24192419
let (tcProj, ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt) = builder.GetCheckResultsAndImplementationsForProject()
24202420
let fileInfo = (Int32.MaxValue, Int32.MaxValue)
24212421
let errors = [| yield! creationErrors; yield! Parser.CreateErrorInfos (tcProj.TcConfig, true, Microsoft.FSharp.Compiler.TcGlobals.DummyFileNameForRangesWithoutASpecificLocation, fileInfo, tcProj.Errors) |]
2422-
FSharpCheckProjectResults (keepAssemblyContents, errors, Some(tcProj.TcGlobals, tcProj.TcImports, tcProj.TcState.Ccu, tcProj.TcState.PartialAssemblySignature, tcProj.TcSymbolUses, tcAssemblyDataOpt, ilAssemRef, tcProj.TcEnvAtEnd.AccessRights, tcAssemblyExprOpt), reactorOps)
2422+
FSharpCheckProjectResults (keepAssemblyContents, errors, Some(tcProj.TcGlobals, tcProj.TcImports, tcProj.TcState.Ccu, tcProj.TcState.PartialAssemblySignature, tcProj.TcSymbolUses, tcProj.TopAttribs, tcAssemblyDataOpt, ilAssemRef, tcProj.TcEnvAtEnd.AccessRights, tcAssemblyExprOpt), reactorOps)
24232423

24242424
/// Get the timestamp that would be on the output if fully built immediately
24252425
member private bc.GetLogicalTimeStampForProject(options) =
@@ -3168,7 +3168,7 @@ type FsiInteractiveChecker(reactorOps: IReactorOperations, tcConfig, tcGlobals,
31683168
| Parser.TypeCheckAborted.No scope ->
31693169
let errors = [| yield! parseErrors; yield! tcErrors |]
31703170
let typeCheckResults = FSharpCheckFileResults (errors,Some scope, None, reactorOps)
3171-
let projectResults = FSharpCheckProjectResults (keepAssemblyContents, errors, Some(tcGlobals, tcImports, scope.ThisCcu, scope.CcuSig, [scope.ScopeSymbolUses], None, mkSimpleAssRef "stdin", tcState.TcEnvFromImpls.AccessRights, None), reactorOps)
3171+
let projectResults = FSharpCheckProjectResults (keepAssemblyContents, errors, Some(tcGlobals, tcImports, scope.ThisCcu, scope.CcuSig, [scope.ScopeSymbolUses], None, None, mkSimpleAssRef "stdin", tcState.TcEnvFromImpls.AccessRights, None), reactorOps)
31723172
parseResults, typeCheckResults, projectResults
31733173
| _ ->
31743174
failwith "unexpected aborted"

tests/service/ProjectAnalysisTests.fs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4505,7 +4505,7 @@ module Project37 =
45054505
let dllName = Path.ChangeExtension(base2, ".dll")
45064506
let projFileName = Path.ChangeExtension(base2, ".fsproj")
45074507
let fileSource1 = """
4508-
[<System.AttributeUsage(System.AttributeTargets.Method)>]
4508+
[<System.AttributeUsage(System.AttributeTargets.Method ||| System.AttributeTargets.Assembly)>]
45094509
type AttrTestAttribute() =
45104510
inherit System.Attribute()
45114511
@@ -4529,6 +4529,9 @@ module Test =
45294529
let withTypeArray = 0
45304530
[<AttrTest([| 0; 1; 2 |])>]
45314531
let withIntArray = 0
4532+
4533+
[<assembly: AttrTest()>]
4534+
do ()
45324535
"""
45334536
File.WriteAllText(fileName1, fileSource1)
45344537
let fileNames = [fileName1]
@@ -4575,4 +4578,7 @@ let ``Test project37 typeof and arrays in attribute constructor arguments`` () =
45754578
let a = attr :?> obj[] |> Array.map (fun t -> t :?> int)
45764579
a |> shouldEqual [| 0; 1; 2 |]
45774580
| _ -> ()
4578-
| _ -> ()
4581+
| _ -> ()
4582+
Project37.wholeProjectResults.AssemblySignature.Attributes
4583+
|> Seq.map (fun a -> a.AttributeType.CompiledName)
4584+
|> Array.ofSeq |> shouldEqual [| "AttrTestAttribute" |]

0 commit comments

Comments
 (0)