From 3aea49828ac2deec3fb0af91879f708ea9fc48ba Mon Sep 17 00:00:00 2001 From: dsyme Date: Tue, 3 Oct 2017 18:46:01 +0100 Subject: [PATCH] whitespace and docs --- src/fsharp/vs/IncrementalBuild.fs | 523 ++++++++++---------- src/fsharp/vs/Reactor.fs | 8 +- src/fsharp/vs/ServiceDeclarationLists.fs | 37 +- src/fsharp/vs/ServiceDeclarationLists.fsi | 17 + src/fsharp/vs/ServiceParamInfoLocations.fs | 72 +-- src/fsharp/vs/ServiceParamInfoLocations.fsi | 19 +- 6 files changed, 373 insertions(+), 303 deletions(-) diff --git a/src/fsharp/vs/IncrementalBuild.fs b/src/fsharp/vs/IncrementalBuild.fs index 0d94b79c542..89c315001a9 100755 --- a/src/fsharp/vs/IncrementalBuild.fs +++ b/src/fsharp/vs/IncrementalBuild.fs @@ -56,15 +56,15 @@ module internal IncrementalBuild = /// Get the Id for the given ScalarBuildRule. member x.Id = match x with - | ScalarInput(id,_) ->id - | ScalarDemultiplex(id,_,_,_) ->id - | ScalarMap(id,_,_,_) ->id + | ScalarInput(id, _) ->id + | ScalarDemultiplex(id, _, _, _) ->id + | ScalarMap(id, _, _, _) ->id /// Get the Name for the givenScalarExpr. member x.Name = match x with - | ScalarInput(_,n) ->n - | ScalarDemultiplex(_,n,_,_) ->n - | ScalarMap(_,n,_,_) ->n + | ScalarInput(_, n) ->n + | ScalarDemultiplex(_, n, _, _) ->n + | ScalarMap(_, n, _, _) ->n /// A build rule with a vector of outputs and VectorBuildRule = @@ -96,19 +96,19 @@ module internal IncrementalBuild = /// Get the Id for the given VectorBuildRule. member x.Id = match x with - | VectorInput(id,_) -> id - | VectorScanLeft(id,_,_,_,_) -> id - | VectorMap(id,_,_,_) -> id - | VectorStamp (id,_,_,_) -> id - | VectorMultiplex(id,_,_,_) -> id + | VectorInput(id, _) -> id + | VectorScanLeft(id, _, _, _, _) -> id + | VectorMap(id, _, _, _) -> id + | VectorStamp (id, _, _, _) -> id + | VectorMultiplex(id, _, _, _) -> id /// Get the Name for the given VectorBuildRule. member x.Name = match x with - | VectorInput(_,n) -> n - | VectorScanLeft(_,n,_,_,_) -> n - | VectorMap(_,n,_,_) -> n - | VectorStamp (_,n,_,_) -> n - | VectorMultiplex(_,n,_,_) -> n + | VectorInput(_, n) -> n + | VectorScanLeft(_, n, _, _, _) -> n + | VectorMap(_, n, _, _) -> n + | VectorStamp (_, n, _, _) -> n + | VectorMultiplex(_, n, _, _) -> n [] type BuildRuleExpr = @@ -159,16 +159,16 @@ module internal IncrementalBuild = let rec visitVector (ve:VectorBuildRule) acc = match ve with | VectorInput _ -> op (VectorBuildRule ve) acc - | VectorScanLeft(_,_,a,i,_) -> op (VectorBuildRule ve) (visitVector i (visitScalar a acc)) - | VectorMap(_,_,i,_) - | VectorStamp (_,_,i,_) -> op (VectorBuildRule ve) (visitVector i acc) - | VectorMultiplex(_,_,i,_) -> op (VectorBuildRule ve) (visitScalar i acc) + | VectorScanLeft(_, _, a, i, _) -> op (VectorBuildRule ve) (visitVector i (visitScalar a acc)) + | VectorMap(_, _, i, _) + | VectorStamp (_, _, i, _) -> op (VectorBuildRule ve) (visitVector i acc) + | VectorMultiplex(_, _, i, _) -> op (VectorBuildRule ve) (visitScalar i acc) and visitScalar (se:ScalarBuildRule) acc = match se with | ScalarInput _ -> op (ScalarBuildRule se) acc - | ScalarDemultiplex(_,_,i,_) -> op (ScalarBuildRule se) (visitVector i acc) - | ScalarMap(_,_,i,_) -> op (ScalarBuildRule se) (visitScalar i acc) + | ScalarDemultiplex(_, _, i, _) -> op (ScalarBuildRule se) (visitVector i acc) + | ScalarMap(_, _, i, _) -> op (ScalarBuildRule se) (visitScalar i acc) let visitRule (expr:BuildRuleExpr) acc = match expr with @@ -182,12 +182,12 @@ module internal IncrementalBuild = // Create the rules. let createRules() = - { RuleList = names |> List.map (function NamedVectorOutput(v) -> v.Name,VectorBuildRule(v.Expr) - | NamedScalarOutput(s) -> s.Name,ScalarBuildRule(s.Expr)) } + { RuleList = names |> List.map (function NamedVectorOutput(v) -> v.Name, VectorBuildRule(v.Expr) + | NamedScalarOutput(s) -> s.Name, ScalarBuildRule(s.Expr)) } // Ensure that all names are unique. - let ensureUniqueNames (expr:BuildRuleExpr) (acc:Map) = - let AddUniqueIdToNameMapping(id,name)= + let ensureUniqueNames (expr:BuildRuleExpr) (acc:Map) = + let AddUniqueIdToNameMapping(id, name)= match acc.TryFind name with | Some priorId -> if id<>priorId then failwith (sprintf "Two build expressions had the same name: %s" name) @@ -195,11 +195,11 @@ module internal IncrementalBuild = | None-> Map.add name id acc let id = expr.Id let name = expr.Name - AddUniqueIdToNameMapping(id,name) + AddUniqueIdToNameMapping(id, name) // Validate the rule tree let validateRules (rules:BuildRules) = - FoldOverBuildRules(rules,ensureUniqueNames,Map.empty) |> ignore + FoldOverBuildRules(rules, ensureUniqueNames, Map.empty) |> ignore // Convert and validate let rules = createRules() @@ -230,27 +230,27 @@ module internal IncrementalBuild = | Available of obj * DateTime * InputSignature /// Get the available result. Throw an exception if not available. - member x.GetAvailable() = match x with Available(o,_,_) ->o | _ -> failwith "No available result" + member x.GetAvailable() = match x with Available(o, _, _) ->o | _ -> failwith "No available result" /// Get the time stamp if available. Otherwise MaxValue. - member x.Timestamp = match x with Available(_,ts,_) -> ts | InProgress(_,ts) -> ts | _ -> DateTime.MaxValue + member x.Timestamp = match x with Available(_, ts, _) -> ts | InProgress(_, ts) -> ts | _ -> DateTime.MaxValue /// Get the time stamp if available. Otherwise MaxValue. - member x.InputSignature = match x with Available(_,_,signature) -> signature | _ -> UnevaluatedInput + member x.InputSignature = match x with Available(_, _, signature) -> signature | _ -> UnevaluatedInput member x.ResultIsInProgress = match x with | InProgress _ -> true | _ -> false - member x.GetInProgressContinuation ctok = match x with | InProgress (f,_) -> f ctok | _ -> failwith "not in progress" - member x.TryGetAvailable() = match x with | InProgress _ | NotAvailable -> None | Available(obj,dt,i) -> Some (obj,dt,i) + member x.GetInProgressContinuation ctok = match x with | InProgress (f, _) -> f ctok | _ -> failwith "not in progress" + member x.TryGetAvailable() = match x with | InProgress _ | NotAvailable -> None | Available(obj, dt, i) -> Some (obj, dt, i) /// An immutable sparse vector of results. - type ResultVector(size,zeroElementTimestamp,map) = + type ResultVector(size, zeroElementTimestamp, map) = let get slot = match Map.tryFind slot map with | Some result ->result | None->NotAvailable - let asList = lazy List.map (fun i->i,get i) [0..size-1] + let asList = lazy List.map (fun i->i, get i) [0..size-1] - static member OfSize(size) = ResultVector(size,DateTime.MinValue,Map.empty) + static member OfSize(size) = ResultVector(size, DateTime.MinValue, Map.empty) member rv.Size = size member rv.Get slot = get slot member rv.Resize(newsize) = @@ -258,7 +258,7 @@ module internal IncrementalBuild = ResultVector(newsize, zeroElementTimestamp, map |> Map.filter(fun s _ -> s < newsize)) else rv - member rv.Set(slot,value) = + member rv.Set(slot, value) = #if DEBUG if slot<0 then failwith "ResultVector slot less than zero" if slot>=size then failwith "ResultVector slot too big" @@ -266,12 +266,12 @@ module internal IncrementalBuild = ResultVector(size, zeroElementTimestamp, Map.add slot value map) member rv.MaxTimestamp() = - let maximize (lasttimestamp:DateTime) (_,result:Result) = max lasttimestamp result.Timestamp + let maximize (lasttimestamp:DateTime) (_, result:Result) = max lasttimestamp result.Timestamp List.fold maximize zeroElementTimestamp (asList.Force()) member rv.Signature() = let l = asList.Force() - let l = l |> List.map (fun (_,result) -> result.InputSignature) + let l = l |> List.map (fun (_, result) -> result.InputSignature) SingleMappedVectorInput (l|>List.toArray) member rv.FoldLeft f s: 'a = List.fold f s (asList.Force()) @@ -302,20 +302,20 @@ module internal IncrementalBuild = member action.Execute(ctok) = cancellable { match action with - | IndexedAction(id,_taskname,slot,slotcount,timestamp,func) -> let res = func ctok in return IndexedResult(id,slot,slotcount,res,timestamp) - | ScalarAction(id,_taskname,timestamp,inputsig,func) -> let! res = func ctok in return ScalarValuedResult(id,res,timestamp,inputsig) - | VectorAction(id,_taskname,timestamp,inputsig,func) -> let! res = func ctok in return VectorValuedResult(id,res,timestamp,inputsig) - | ResizeResultAction(id,slotcount) -> return ResizeResult(id,slotcount) + | IndexedAction(id, _taskname, slot, slotcount, timestamp, func) -> let res = func ctok in return IndexedResult(id, slot, slotcount, res, timestamp) + | ScalarAction(id, _taskname, timestamp, inputsig, func) -> let! res = func ctok in return ScalarValuedResult(id, res, timestamp, inputsig) + | VectorAction(id, _taskname, timestamp, inputsig, func) -> let! res = func ctok in return VectorValuedResult(id, res, timestamp, inputsig) + | ResizeResultAction(id, slotcount) -> return ResizeResult(id, slotcount) } /// A set of build rules and the corresponding, possibly partial, results from building. [] - type PartialBuild(rules:BuildRules, results:Map) = + type PartialBuild(rules:BuildRules, results:Map) = member bt.Rules = rules member bt.Results = results /// Given an expression, find the expected width. - let rec GetVectorWidthByExpr(bt:PartialBuild,ve:VectorBuildRule) = + let rec GetVectorWidthByExpr(bt:PartialBuild, ve:VectorBuildRule) = let id = ve.Id let KnownValue() = match bt.Results.TryFind id with @@ -325,10 +325,10 @@ module internal IncrementalBuild = | _ -> failwith "Expected vector to have vector result." | None-> None match ve with - | VectorScanLeft(_,_,_,i,_) - | VectorMap(_,_,i,_) - | VectorStamp (_,_,i,_) -> - match GetVectorWidthByExpr(bt,i) with + | VectorScanLeft(_, _, _, i, _) + | VectorMap(_, _, i, _) + | VectorStamp (_, _, i, _) -> + match GetVectorWidthByExpr(bt, i) with | Some _ as r -> r | None -> KnownValue() | VectorInput _ @@ -336,85 +336,85 @@ module internal IncrementalBuild = /// Given an expression name, get the corresponding expression. let GetTopLevelExprByName(bt:PartialBuild, seek:string) = - bt.Rules.RuleList |> List.filter(fun(name,_) ->name=seek) |> List.map (fun(_,root) ->root) |> List.head + bt.Rules.RuleList |> List.filter(fun(name, _) ->name=seek) |> List.map (fun(_, root) ->root) |> List.head /// Get an expression matching the given name. let GetExprByName(bt:PartialBuild, node:INode): BuildRuleExpr = let matchName (expr:BuildRuleExpr) (acc:BuildRuleExpr option): BuildRuleExpr option = if expr.Name = node.Name then Some expr else acc - let matchOption = FoldOverBuildRules(bt.Rules,matchName,None) + let matchOption = FoldOverBuildRules(bt.Rules, matchName, None) Option.get matchOption // Given an Id, find the corresponding expression. let GetExprById(bt:PartialBuild, seek:Id): BuildRuleExpr= let rec vectorExprOfId ve = match ve with - | VectorInput(id,_) ->if seek=id then Some (VectorBuildRule ve) else None - | VectorScanLeft(id,_,a,i,_) -> + | VectorInput(id, _) ->if seek=id then Some (VectorBuildRule ve) else None + | VectorScanLeft(id, _, a, i, _) -> if seek=id then Some (VectorBuildRule ve) else let result = scalarExprOfId(a) match result with Some _ -> result | None->vectorExprOfId i - | VectorMap(id,_,i,_) ->if seek=id then Some (VectorBuildRule ve) else vectorExprOfId i - | VectorStamp (id,_,i,_) ->if seek=id then Some (VectorBuildRule ve) else vectorExprOfId i - | VectorMultiplex(id,_,i,_) ->if seek=id then Some (VectorBuildRule ve) else scalarExprOfId i + | VectorMap(id, _, i, _) ->if seek=id then Some (VectorBuildRule ve) else vectorExprOfId i + | VectorStamp (id, _, i, _) ->if seek=id then Some (VectorBuildRule ve) else vectorExprOfId i + | VectorMultiplex(id, _, i, _) ->if seek=id then Some (VectorBuildRule ve) else scalarExprOfId i and scalarExprOfId se = match se with - | ScalarInput(id,_) ->if seek=id then Some (ScalarBuildRule se) else None - | ScalarDemultiplex(id,_,i,_) ->if seek=id then Some (ScalarBuildRule se) else vectorExprOfId i - | ScalarMap(id,_,i,_) ->if seek=id then Some (ScalarBuildRule se) else scalarExprOfId i + | ScalarInput(id, _) ->if seek=id then Some (ScalarBuildRule se) else None + | ScalarDemultiplex(id, _, i, _) ->if seek=id then Some (ScalarBuildRule se) else vectorExprOfId i + | ScalarMap(id, _, i, _) ->if seek=id then Some (ScalarBuildRule se) else scalarExprOfId i let exprOfId(expr:BuildRuleExpr) = match expr with | ScalarBuildRule se ->scalarExprOfId se | VectorBuildRule ve ->vectorExprOfId ve - let exprs = bt.Rules.RuleList |> List.map (fun(_,root) ->exprOfId(root)) |> List.filter Option.isSome + let exprs = bt.Rules.RuleList |> List.map (fun(_, root) ->exprOfId(root)) |> List.filter Option.isSome match exprs with | Some expr :: _ -> expr | _ -> failwith (sprintf "GetExprById did not find an expression for Id") let GetVectorWidthById (bt:PartialBuild) seek = - match GetExprById(bt,seek) with + match GetExprById(bt, seek) with | ScalarBuildRule _ ->failwith "Attempt to get width of scalar." - | VectorBuildRule ve -> Option.get (GetVectorWidthByExpr(bt,ve)) + | VectorBuildRule ve -> Option.get (GetVectorWidthByExpr(bt, ve)) let GetScalarExprResult (bt:PartialBuild, se:ScalarBuildRule) = match bt.Results.TryFind (se.Id) with | Some resultSet -> - match se,resultSet with - | ScalarInput _,ScalarResult r - | ScalarMap _,ScalarResult r - | ScalarDemultiplex _,ScalarResult r ->r + match se, resultSet with + | ScalarInput _, ScalarResult r + | ScalarMap _, ScalarResult r + | ScalarDemultiplex _, ScalarResult r ->r | _ ->failwith "GetScalarExprResult had no match" | None->NotAvailable let GetVectorExprResultVector (bt:PartialBuild, ve:VectorBuildRule) = match bt.Results.TryFind (ve.Id) with | Some resultSet -> - match ve,resultSet with - | VectorScanLeft _,VectorResult rv - | VectorMap _,VectorResult rv - | VectorInput _,VectorResult rv - | VectorStamp _,VectorResult rv - | VectorMultiplex _,VectorResult rv -> Some rv + match ve, resultSet with + | VectorScanLeft _, VectorResult rv + | VectorMap _, VectorResult rv + | VectorInput _, VectorResult rv + | VectorStamp _, VectorResult rv + | VectorMultiplex _, VectorResult rv -> Some rv | _ -> failwith "GetVectorExprResultVector had no match" | None->None let GetVectorExprResult (bt:PartialBuild, ve:VectorBuildRule, slot) = match bt.Results.TryFind ve.Id with | Some resultSet -> - match ve,resultSet with - | VectorScanLeft _,VectorResult rv - | VectorMap _,VectorResult rv - | VectorInput _,VectorResult rv - | VectorStamp _,VectorResult rv -> rv.Get slot - | VectorMultiplex _,VectorResult rv -> rv.Get slot + match ve, resultSet with + | VectorScanLeft _, VectorResult rv + | VectorMap _, VectorResult rv + | VectorInput _, VectorResult rv + | VectorStamp _, VectorResult rv -> rv.Get slot + | VectorMultiplex _, VectorResult rv -> rv.Get slot | _ -> failwith "GetVectorExprResult had no match" | None->NotAvailable /// Get the maximum build stamp for an output. - let MaxTimestamp(bt:PartialBuild,id) = + let MaxTimestamp(bt:PartialBuild, id) = match bt.Results.TryFind id with | Some resultset -> match resultset with @@ -422,7 +422,7 @@ module internal IncrementalBuild = | VectorResult rv -> rv.MaxTimestamp() | None -> DateTime.MaxValue - let Signature(bt:PartialBuild,id) = + let Signature(bt:PartialBuild, id) = match bt.Results.TryFind id with | Some resultset -> match resultset with @@ -453,83 +453,83 @@ module internal IncrementalBuild = | Scalar of INode * obj /// Declare a named scalar output. - static member ScalarInput (node:Scalar<'T>,value: 'T) = BuildInput.Scalar(node,box value) - static member VectorInput(node:Vector<'T>,values: 'T list) = BuildInput.Vector(node,List.map box values) + static member ScalarInput (node:Scalar<'T>, value: 'T) = BuildInput.Scalar(node, box value) + static member VectorInput(node:Vector<'T>, values: 'T list) = BuildInput.Vector(node, List.map box values) let AvailableAllResultsOfExpr bt expr = let msg = "Expected all results to be available" - AllResultsOfExpr (function Available(o,_,_) -> o | _ -> failwith msg) bt expr + AllResultsOfExpr (function Available(o, _, _) -> o | _ -> failwith msg) bt expr /// Bind a set of build rules to a set of input values. let ToBound(buildRules:BuildRules, inputs: BuildInput list) = let now = DateTime.Now - let rec applyScalarExpr(se,results) = + let rec applyScalarExpr(se, results) = match se with - | ScalarInput(id,n) -> + | ScalarInput(id, n) -> let matches = [ for input in inputs do match input with | BuildInput.Scalar (node, value) -> if node.Name = n then - yield ScalarResult(Available(value,now,BoundInputScalar)) + yield ScalarResult(Available(value, now, BoundInputScalar)) | _ -> () ] List.foldBack (Map.add id) matches results - | ScalarMap(_,_,se,_) ->applyScalarExpr(se,results) - | ScalarDemultiplex(_,_,ve,_) ->ApplyVectorExpr(ve,results) - and ApplyVectorExpr(ve,results) = + | ScalarMap(_, _, se, _) ->applyScalarExpr(se, results) + | ScalarDemultiplex(_, _, ve, _) ->ApplyVectorExpr(ve, results) + and ApplyVectorExpr(ve, results) = match ve with - | VectorInput(id,n) -> + | VectorInput(id, n) -> let matches = [ for input in inputs do match input with | BuildInput.Scalar _ -> () | BuildInput.Vector (node, values) -> if node.Name = n then - let results = values|>List.mapi(fun i value->i,Available(value,now,BoundInputVector)) - yield VectorResult(ResultVector(values.Length,DateTime.MinValue,results|>Map.ofList)) ] + let results = values|>List.mapi(fun i value->i, Available(value, now, BoundInputVector)) + yield VectorResult(ResultVector(values.Length, DateTime.MinValue, results|>Map.ofList)) ] List.foldBack (Map.add id) matches results - | VectorScanLeft(_,_,a,i,_) ->ApplyVectorExpr(i,applyScalarExpr(a,results)) - | VectorMap(_,_,i,_) - | VectorStamp (_,_,i,_) ->ApplyVectorExpr(i,results) - | VectorMultiplex(_,_,i,_) ->applyScalarExpr(i,results) + | VectorScanLeft(_, _, a, i, _) ->ApplyVectorExpr(i, applyScalarExpr(a, results)) + | VectorMap(_, _, i, _) + | VectorStamp (_, _, i, _) ->ApplyVectorExpr(i, results) + | VectorMultiplex(_, _, i, _) ->applyScalarExpr(i, results) let applyExpr expr results = match expr with - | ScalarBuildRule se ->applyScalarExpr(se,results) - | VectorBuildRule ve ->ApplyVectorExpr(ve,results) + | ScalarBuildRule se ->applyScalarExpr(se, results) + | VectorBuildRule ve ->ApplyVectorExpr(ve, results) // Place vector inputs into results map. let results = List.foldBack applyExpr (buildRules.RuleList |> List.map snd) Map.empty - PartialBuild(buildRules,results) + PartialBuild(buildRules, results) type Target = Target of INode * int option /// Visit each executable action necessary to evaluate the given output (with an optional slot in a /// vector output). Call actionFunc with the given accumulator. let ForeachAction cache ctok (Target(output, optSlot)) bt (actionFunc:Action -> 'T -> 'T) (acc:'T) = - let seen = Dictionary() + let seen = Dictionary() let isSeen id = if seen.ContainsKey id then true else seen.[id] <- true false - let shouldEvaluate(bt,currentsig:InputSignature,id) = + let shouldEvaluate(bt, currentsig:InputSignature, id) = if currentsig.IsEvaluated then - currentsig <> Signature(bt,id) + currentsig <> Signature(bt, id) else false /// Make sure the result vector saved matches the size of expr - let resizeVectorExpr(ve:VectorBuildRule,acc) = - match GetVectorWidthByExpr(bt,ve) with + let resizeVectorExpr(ve:VectorBuildRule, acc) = + match GetVectorWidthByExpr(bt, ve) with | Some expectedWidth -> match bt.Results.TryFind ve.Id with | Some found -> match found with | VectorResult rv -> if rv.Size <> expectedWidth then - actionFunc (ResizeResultAction(ve.Id ,expectedWidth)) acc + actionFunc (ResizeResultAction(ve.Id , expectedWidth)) acc else acc | _ -> acc | None -> acc @@ -539,25 +539,25 @@ module internal IncrementalBuild = if isSeen ve.Id then acc else - let acc = resizeVectorExpr(ve,acc) + let acc = resizeVectorExpr(ve, acc) match ve with | VectorInput _ -> acc - | VectorScanLeft(id,taskname,accumulatorExpr,inputExpr,func) -> + | VectorScanLeft(id, taskname, accumulatorExpr, inputExpr, func) -> let acc = - match GetVectorWidthByExpr(bt,ve) with + match GetVectorWidthByExpr(bt, ve) with | Some cardinality -> let limit = match optSlot with None -> cardinality | Some slot -> (slot+1) let Scan slot = let accumulatorResult = - if slot=0 then GetScalarExprResult (bt,accumulatorExpr) - else GetVectorExprResult (bt,ve,slot-1) + if slot=0 then GetScalarExprResult (bt, accumulatorExpr) + else GetVectorExprResult (bt, ve, slot-1) - let inputResult = GetVectorExprResult (bt,inputExpr,slot) - match accumulatorResult,inputResult with - | Available(accumulator,accumulatortimesamp,_accumulatorInputSig),Available(input,inputtimestamp,_inputSig) -> + let inputResult = GetVectorExprResult (bt, inputExpr, slot) + match accumulatorResult, inputResult with + | Available(accumulator, accumulatortimesamp, _accumulatorInputSig), Available(input, inputtimestamp, _inputSig) -> let inputtimestamp = max inputtimestamp accumulatortimesamp - let prevoutput = GetVectorExprResult (bt,ve,slot) + let prevoutput = GetVectorExprResult (bt, ve, slot) let outputtimestamp = prevoutput.Timestamp let scanOpOpt = if inputtimestamp <> outputtimestamp then @@ -568,7 +568,7 @@ module internal IncrementalBuild = // up-to-date and complete, no work required None match scanOpOpt with - | Some scanOp -> Some (actionFunc (IndexedAction(id,taskname,slot,cardinality,inputtimestamp,scanOp)) acc) + | Some scanOp -> Some (actionFunc (IndexedAction(id, taskname, slot, cardinality, inputtimestamp, scanOp)) acc) | None -> None | _ -> None @@ -580,23 +580,23 @@ module internal IncrementalBuild = | VectorMap(id, taskname, inputExpr, func) -> let acc = - match GetVectorWidthByExpr(bt,ve) with + match GetVectorWidthByExpr(bt, ve) with | Some cardinality -> if cardinality=0 then // For vector length zero, just propagate the prior timestamp. - let inputtimestamp = MaxTimestamp(bt,inputExpr.Id) - let outputtimestamp = MaxTimestamp(bt,id) + let inputtimestamp = MaxTimestamp(bt, inputExpr.Id) + let outputtimestamp = MaxTimestamp(bt, id) if inputtimestamp <> outputtimestamp then - actionFunc (VectorAction(id,taskname,inputtimestamp,EmptyTimeStampedInput inputtimestamp, fun _ -> cancellable.Return [||])) acc + actionFunc (VectorAction(id, taskname, inputtimestamp, EmptyTimeStampedInput inputtimestamp, fun _ -> cancellable.Return [||])) acc else acc else let MapResults acc slot = - let inputtimestamp = GetVectorExprResult(bt,inputExpr,slot).Timestamp - let outputtimestamp = GetVectorExprResult(bt,ve,slot).Timestamp + let inputtimestamp = GetVectorExprResult(bt, inputExpr, slot).Timestamp + let outputtimestamp = GetVectorExprResult(bt, ve, slot).Timestamp if inputtimestamp <> outputtimestamp then let OneToOneOp ctok = - Eventually.Done (func ctok (GetVectorExprResult(bt,inputExpr,slot).GetAvailable())) - actionFunc (IndexedAction(id,taskname,slot,cardinality,inputtimestamp,OneToOneOp)) acc + Eventually.Done (func ctok (GetVectorExprResult(bt, inputExpr, slot).GetAvailable())) + actionFunc (IndexedAction(id, taskname, slot, cardinality, inputtimestamp, OneToOneOp)) acc else acc match optSlot with | None -> @@ -611,24 +611,24 @@ module internal IncrementalBuild = // For every result that is available, check time stamps. let acc = - match GetVectorWidthByExpr(bt,ve) with + match GetVectorWidthByExpr(bt, ve) with | Some cardinality -> if cardinality=0 then // For vector length zero, just propagate the prior timestamp. - let inputtimestamp = MaxTimestamp(bt,inputExpr.Id) - let outputtimestamp = MaxTimestamp(bt,id) + let inputtimestamp = MaxTimestamp(bt, inputExpr.Id) + let outputtimestamp = MaxTimestamp(bt, id) if inputtimestamp <> outputtimestamp then - actionFunc (VectorAction(id,taskname,inputtimestamp,EmptyTimeStampedInput inputtimestamp,fun _ -> cancellable.Return [||])) acc + actionFunc (VectorAction(id, taskname, inputtimestamp, EmptyTimeStampedInput inputtimestamp, fun _ -> cancellable.Return [||])) acc else acc else let checkStamp acc slot = - let inputresult = GetVectorExprResult (bt,inputExpr,slot) + let inputresult = GetVectorExprResult (bt, inputExpr, slot) match inputresult with - | Available(ires,_,_) -> - let oldtimestamp = GetVectorExprResult(bt,ve,slot).Timestamp + | Available(ires, _, _) -> + let oldtimestamp = GetVectorExprResult(bt, ve, slot).Timestamp let newtimestamp = func cache ctok ires if newtimestamp <> oldtimestamp then - actionFunc (IndexedAction(id,taskname,slot,cardinality,newtimestamp, fun _ -> Eventually.Done ires)) acc + actionFunc (IndexedAction(id, taskname, slot, cardinality, newtimestamp, fun _ -> Eventually.Done ires)) acc else acc | _ -> acc match optSlot with @@ -641,12 +641,12 @@ module internal IncrementalBuild = | VectorMultiplex(id, taskname, inputExpr, func) -> let acc = - match GetScalarExprResult (bt,inputExpr) with - | Available(inp,inputtimestamp,inputsig) -> - let outputtimestamp = MaxTimestamp(bt,id) + match GetScalarExprResult (bt, inputExpr) with + | Available(inp, inputtimestamp, inputsig) -> + let outputtimestamp = MaxTimestamp(bt, id) if inputtimestamp <> outputtimestamp then let MultiplexOp ctok = func ctok inp |> cancellable.Return - actionFunc (VectorAction(id,taskname,inputtimestamp,inputsig,MultiplexOp)) acc + actionFunc (VectorAction(id, taskname, inputtimestamp, inputsig, MultiplexOp)) acc else acc | _ -> acc visitScalar inputExpr acc @@ -656,39 +656,39 @@ module internal IncrementalBuild = else match se with | ScalarInput _ -> acc - | ScalarDemultiplex (id,taskname,inputExpr,func) -> + | ScalarDemultiplex (id, taskname, inputExpr, func) -> let acc = - match GetVectorExprResultVector (bt,inputExpr) with + match GetVectorExprResultVector (bt, inputExpr) with | Some inputresult -> let currentsig = inputresult.Signature() - if shouldEvaluate(bt,currentsig,id) then + if shouldEvaluate(bt, currentsig, id) then let inputtimestamp = MaxTimestamp(bt, inputExpr.Id) let DemultiplexOp ctok = cancellable { let input = AvailableAllResultsOfExpr bt inputExpr |> List.toArray return! func ctok input } - actionFunc (ScalarAction(id,taskname,inputtimestamp,currentsig,DemultiplexOp)) acc + actionFunc (ScalarAction(id, taskname, inputtimestamp, currentsig, DemultiplexOp)) acc else acc | None -> acc visitVector None inputExpr acc - | ScalarMap (id,taskname,inputExpr,func) -> + | ScalarMap (id, taskname, inputExpr, func) -> let acc = - match GetScalarExprResult (bt,inputExpr) with - | Available(inp,inputtimestamp,inputsig) -> + match GetScalarExprResult (bt, inputExpr) with + | Available(inp, inputtimestamp, inputsig) -> let outputtimestamp = MaxTimestamp(bt, id) if inputtimestamp <> outputtimestamp then let MapOp ctok = func ctok inp |> cancellable.Return - actionFunc (ScalarAction(id,taskname,inputtimestamp,inputsig,MapOp)) acc + actionFunc (ScalarAction(id, taskname, inputtimestamp, inputsig, MapOp)) acc else acc | _ -> acc visitScalar inputExpr acc - let expr = bt.Rules.RuleList |> List.find (fun (s,_) -> s = output.Name) |> snd + let expr = bt.Rules.RuleList |> List.find (fun (s, _) -> s = output.Name) |> snd match expr with | ScalarBuildRule se -> visitScalar se acc | VectorBuildRule ve -> visitVector optSlot ve acc @@ -701,14 +701,14 @@ module internal IncrementalBuild = /// Compute the max timestamp on all available inputs let ComputeMaxTimeStamp cache ctok output (bt: PartialBuild) acc = - let expr = bt.Rules.RuleList |> List.find (fun (s,_) -> s = output) |> snd + let expr = bt.Rules.RuleList |> List.find (fun (s, _) -> s = output) |> snd match expr with | VectorBuildRule (VectorStamp (_id, _taskname, inputExpr, func) as ve) -> - match GetVectorWidthByExpr(bt,ve) with + match GetVectorWidthByExpr(bt, ve) with | Some cardinality -> let CheckStamp acc slot = - match GetVectorExprResult (bt,inputExpr,slot) with - | Available(ires,_,_) -> max acc (func cache ctok ires) + match GetVectorExprResult (bt, inputExpr, slot) with + | Available(ires, _, _) -> max acc (func cache ctok ires) | _ -> acc [0..cardinality-1] |> List.fold CheckStamp acc | None -> acc @@ -717,29 +717,29 @@ module internal IncrementalBuild = /// Given the result of a single action, apply that action to the Build - let ApplyResult(actionResult:ActionResult,bt:PartialBuild) = + let ApplyResult(actionResult:ActionResult, bt:PartialBuild) = match actionResult with - | ResizeResult(id,slotcount) -> + | ResizeResult(id, slotcount) -> match bt.Results.TryFind id with | Some resultSet -> match resultSet with | VectorResult rv -> let rv = rv.Resize(slotcount) let results = Map.add id (VectorResult rv) bt.Results - PartialBuild(bt.Rules,results) + PartialBuild(bt.Rules, results) | _ -> failwith "Unexpected" | None -> failwith "Unexpected" - | ScalarValuedResult(id,value,timestamp,inputsig) -> - PartialBuild(bt.Rules, Map.add id (ScalarResult(Available(value,timestamp,inputsig))) bt.Results) - | VectorValuedResult(id,values,timestamp,inputsig) -> + | ScalarValuedResult(id, value, timestamp, inputsig) -> + PartialBuild(bt.Rules, Map.add id (ScalarResult(Available(value, timestamp, inputsig))) bt.Results) + | VectorValuedResult(id, values, timestamp, inputsig) -> let Append acc slot = - Map.add slot (Available(values.[slot],timestamp,inputsig)) acc + Map.add slot (Available(values.[slot], timestamp, inputsig)) acc let results = [0..values.Length-1]|>List.fold Append Map.empty - let results = VectorResult(ResultVector(values.Length,timestamp,results)) + let results = VectorResult(ResultVector(values.Length, timestamp, results)) let bt = PartialBuild(bt.Rules, Map.add id results bt.Results) bt - | IndexedResult(id,index,slotcount,value,timestamp) -> + | IndexedResult(id, index, slotcount, value, timestamp) -> let width = GetVectorWidthById bt id let priorResults = bt.Results.TryFind id let prior = @@ -751,10 +751,10 @@ module internal IncrementalBuild = let result = match value with | Eventually.Done res -> - Available(res,timestamp, IndexedValueElement timestamp) + Available(res, timestamp, IndexedValueElement timestamp) | Eventually.NotYetDone f -> - InProgress (f,timestamp) - let results = rv.Resize(slotcount).Set(index,result) + InProgress (f, timestamp) + let results = rv.Resize(slotcount).Set(index, result) PartialBuild(bt.Rules, Map.add id (VectorResult(results)) bt.Results) | _ -> failwith "Unexpected" @@ -767,7 +767,7 @@ module internal IncrementalBuild = let ExecuteApply (ctok: CompilationThreadToken) save (action:Action) bt = cancellable { let! actionResult = action.Execute(ctok) - let newBt = ApplyResult(actionResult,bt) + let newBt = ApplyResult(actionResult, bt) save ctok newBt return newBt } @@ -775,7 +775,7 @@ module internal IncrementalBuild = /// Evaluate the result of a single output let EvalLeafsFirst cache ctok save target bt = - let rec eval(bt,gen) = + let rec eval(bt, gen) = cancellable { #if DEBUG // This can happen, for example, if there is a task whose timestamp never stops increasing. @@ -786,15 +786,15 @@ module internal IncrementalBuild = let worklist = CollectActions cache target bt let! newBt = - (bt,worklist) ||> Cancellable.fold (fun bt action -> + (bt, worklist) ||> Cancellable.fold (fun bt action -> if injectCancellationFault then Cancellable.canceled() else ExecuteApply ctok save action bt) - if newBt=bt then return bt else return! eval(newBt,gen+1) + if newBt=bt then return bt else return! eval(newBt, gen+1) } - eval(bt,0) + eval(bt, 0) /// Evaluate one step of the build. Call the 'save' function to save the intermediate result. let Step cache ctok save target (bt:PartialBuild) = @@ -814,7 +814,7 @@ module internal IncrementalBuild = /// Evaluate an output of the build. /// /// Intermediate progress along the way may be saved through the use of the 'save' function. - let Eval cache ctok save node bt = EvalLeafsFirst cache ctok save (Target(node,None)) bt + let Eval cache ctok save node bt = EvalLeafsFirst cache ctok save (Target(node, None)) bt /// Evaluate an output of the build. /// @@ -831,47 +831,47 @@ module internal IncrementalBuild = ComputeMaxTimeStamp cache ctok target bt DateTime.MinValue /// Get a scalar vector. Result must be available - let GetScalarResult<'T>(node:Scalar<'T>,bt): ('T*DateTime) option = - match GetTopLevelExprByName(bt,node.Name) with + let GetScalarResult<'T>(node:Scalar<'T>, bt): ('T*DateTime) option = + match GetTopLevelExprByName(bt, node.Name) with | ScalarBuildRule se -> match bt.Results.TryFind se.Id with | Some result -> match result with | ScalarResult(sr) -> match sr.TryGetAvailable() with - | Some (r,timestamp,_) -> Some (downcast r, timestamp) + | Some (r, timestamp, _) -> Some (downcast r, timestamp) | None -> None | _ ->failwith "Expected a scalar result." | None->None | VectorBuildRule _ -> failwith "Expected scalar." /// Get a result vector. All results must be available or thrown an exception. - let GetVectorResult<'T>(node:Vector<'T>,bt): 'T[] = - match GetTopLevelExprByName(bt,node.Name) with + let GetVectorResult<'T>(node:Vector<'T>, bt): 'T[] = + match GetTopLevelExprByName(bt, node.Name) with | ScalarBuildRule _ -> failwith "Expected vector." | VectorBuildRule ve -> AvailableAllResultsOfExpr bt ve |> List.map unbox |> Array.ofList /// Get an element of vector result or None if there were no results. - let GetVectorResultBySlot<'T>(node:Vector<'T>,slot,bt): ('T*DateTime) option = - match GetTopLevelExprByName(bt,node.Name) with + let GetVectorResultBySlot<'T>(node:Vector<'T>, slot, bt): ('T*DateTime) option = + match GetTopLevelExprByName(bt, node.Name) with | ScalarBuildRule _ -> failwith "Expected vector expression" | VectorBuildRule ve -> - match GetVectorExprResult(bt,ve,slot).TryGetAvailable() with - | Some (o,timestamp,_) -> Some (downcast o,timestamp) + match GetVectorExprResult(bt, ve, slot).TryGetAvailable() with + | Some (o, timestamp, _) -> Some (downcast o, timestamp) | None->None /// Given an input value, find the corresponding slot. - let TryGetSlotByInput<'T>(node:Vector<'T>,build:PartialBuild,found:'T->bool): int option = - let expr = GetExprByName(build,node) + let TryGetSlotByInput<'T>(node:Vector<'T>, build:PartialBuild, found:'T->bool): int option = + let expr = GetExprByName(build, node) let id = expr.Id match build.Results.TryFind id with | None -> None | Some resultSet -> match resultSet with | VectorResult rv -> - let MatchNames acc (slot,result) = + let MatchNames acc (slot, result) = match result with - | Available(o,_,_) -> + | Available(o, _, _) -> let o = o :?> 'T if found o then Some slot else acc | _ -> acc @@ -887,7 +887,7 @@ module internal IncrementalBuild = /// Declares a vector build input. let InputVector<'T> name = - let expr = VectorInput(NextId(),name) + let expr = VectorInput(NextId(), name) { new Vector<'T> interface IVector with override __.Name = name @@ -895,7 +895,7 @@ module internal IncrementalBuild = /// Declares a scalar build input. let InputScalar<'T> name = - let expr = ScalarInput(NextId(),name) + let expr = ScalarInput(NextId(), name) { new Scalar<'T> interface IScalar with override __.Name = name @@ -906,7 +906,7 @@ module internal IncrementalBuild = /// Maps one vector to another using the given function. let Map (taskname:string) (task: CompilationThreadToken -> 'I -> 'O) (input:Vector<'I>): Vector<'O> = let input = input.Expr - let expr = VectorMap(NextId(),taskname,input,(fun ctok x -> box (task ctok (unbox x)))) + let expr = VectorMap(NextId(), taskname, input, (fun ctok x -> box (task ctok (unbox x)))) { new Vector<'O> interface IVector with override __.Name = taskname @@ -919,7 +919,7 @@ module internal IncrementalBuild = let BoxingScanLeft ctok a i = Eventually.box(task ctok (unbox a) (unbox i)) let acc = acc.Expr let input = input.Expr - let expr = VectorScanLeft(NextId(),taskname,acc,input,BoxingScanLeft) + let expr = VectorScanLeft(NextId(), taskname, acc, input, BoxingScanLeft) { new Vector<'A> interface IVector with override __.Name = taskname @@ -933,7 +933,7 @@ module internal IncrementalBuild = return box res } let input = input.Expr - let expr = ScalarDemultiplex(NextId(),taskname,input,BoxingDemultiplex) + let expr = ScalarDemultiplex(NextId(), taskname, input, BoxingDemultiplex) { new Scalar<'O> interface IScalar with override __.Name = taskname @@ -943,7 +943,7 @@ module internal IncrementalBuild = /// timestamp specified by the passed-in function. let Stamp (taskname:string) (task: TimeStampCache -> CompilationThreadToken -> 'I -> DateTime) (input:Vector<'I>): Vector<'I> = let input = input.Expr - let expr = VectorStamp (NextId(),taskname,input,(fun cache ctok x -> task cache ctok (unbox x))) + let expr = VectorStamp (NextId(), taskname, input, (fun cache ctok x -> task cache ctok (unbox x))) { new Vector<'I> interface IVector with override __.Name = taskname @@ -957,15 +957,18 @@ module internal IncrementalBuild = /// Declare build outputs and bind them to real values. type BuildDescriptionScope() = let mutable outputs = [] + /// Declare a named scalar output. member b.DeclareScalarOutput(output:Scalar<'T>)= outputs <- NamedScalarOutput(output) :: outputs + /// Declare a named vector output. member b.DeclareVectorOutput(output:Vector<'T>)= outputs <- NamedVectorOutput(output) :: outputs + /// Set the concrete inputs for this build member b.GetInitialPartialBuild(inputs:BuildInput list) = - ToBound(ToBuild outputs,inputs) + ToBound(ToBuild outputs, inputs) @@ -1034,45 +1037,49 @@ type TypeCheckAccumulator = /// Global service state type FrameworkImportsCacheKey = (*resolvedpath*)string list * string * (*TargetFrameworkDirectories*)string list* (*fsharpBinaries*)string +/// Represents a cache of 'framework' references that can be shared betweeen multiple incremental builds type FrameworkImportsCache(keepStrongly) = // Mutable collection protected via CompilationThreadToken - let frameworkTcImportsCache = AgedLookup(keepStrongly, areSimilar=(fun (x,y) -> x = y)) + let frameworkTcImportsCache = AgedLookup(keepStrongly, areSimilar=(fun (x, y) -> x = y)) + /// Reduce the size of the cache in low-memory scenarios member __.Downsize(ctok) = frameworkTcImportsCache.Resize(ctok, keepStrongly=0) + + /// Clear the cache member __.Clear(ctok) = frameworkTcImportsCache.Clear(ctok) /// This function strips the "System" assemblies from the tcConfig and returns a age-cached TcImports for them. member __.Get(ctok, tcConfig:TcConfig) = cancellable { // Split into installed and not installed. - let frameworkDLLs,nonFrameworkResolutions,unresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(ctok, tcConfig) + let frameworkDLLs, nonFrameworkResolutions, unresolved = TcAssemblyResolutions.SplitNonFoundationalResolutions(ctok, tcConfig) let frameworkDLLsKey = frameworkDLLs |> List.map (fun ar->ar.resolvedPath) // The cache key. Just the minimal data. |> List.sort // Sort to promote cache hits. - let! tcGlobals,frameworkTcImports = + let! tcGlobals, frameworkTcImports = cancellable { // Prepare the frameworkTcImportsCache // // The data elements in this key are very important. There should be nothing else in the TcConfig that logically affects // the import of a set of framework DLLs into F# CCUs. That is, the F# CCUs that result from a set of DLLs (including // FSharp.Core.dll and mscorlib.dll) must be logically invariant of all the other compiler configuration parameters. - let key = (frameworkDLLsKey, + let key = (frameworkDLLsKey, tcConfig.primaryAssembly.Name, - tcConfig.GetTargetFrameworkDirectories(), + tcConfig.GetTargetFrameworkDirectories(), tcConfig.fsharpBinariesDir) match frameworkTcImportsCache.TryGet (ctok, key) with | Some res -> return res | None -> let tcConfigP = TcConfigProvider.Constant(tcConfig) - let! ((tcGlobals,tcImports) as res) = TcImports.BuildFrameworkTcImports (ctok, tcConfigP, frameworkDLLs, nonFrameworkResolutions) + let! ((tcGlobals, tcImports) as res) = TcImports.BuildFrameworkTcImports (ctok, tcConfigP, frameworkDLLs, nonFrameworkResolutions) frameworkTcImportsCache.Put(ctok, key, res) - return tcGlobals,tcImports + return tcGlobals, tcImports } - return tcGlobals,frameworkTcImports,nonFrameworkResolutions,unresolved + return tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolved } @@ -1084,6 +1091,8 @@ type FrameworkImportsCache(keepStrongly) = // various steps of the process. //----------------------------------------------------------------------------------- + +/// Represents the interim state of checking an assembly type PartialCheckResults = { TcState: TcState TcImports: TcImports @@ -1115,9 +1124,9 @@ type PartialCheckResults = [] module Utilities = - let TryFindStringAttribute tcGlobals attribSpec attribs = + let TryFindFSharpStringAttribute tcGlobals attribSpec attribs = match TryFindFSharpAttribute tcGlobals attribSpec attribs with - | Some (Attrib(_,_,[ AttribStringArg(s) ],_,_,_,_)) -> Some s + | Some (Attrib(_, _, [ AttribStringArg(s) ], _, _, _, _)) -> Some s | _ -> None /// The implementation of the information needed by TcImports in CompileOps.fs for an F# assembly reference. @@ -1125,7 +1134,7 @@ module Utilities = /// Constructs the build data (IRawFSharpAssemblyData) representing the assembly when used /// as a cross-assembly reference. Note the assembly has not been generated on disk, so this is /// a virtualized view of the assembly contents as computed by background checking. -type RawFSharpAssemblyDataBackedByLanguageService (tcConfig,tcGlobals,tcState:TcState,outfile,topAttrs,assemblyName,ilAssemRef) = +type RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState:TcState, outfile, topAttrs, assemblyName, ilAssemRef) = /// Try to find an attribute that takes a string argument @@ -1133,7 +1142,7 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig,tcGlobals,tcState:Tc let exportRemapping = MakeExportRemapping generatedCcu generatedCcu.Contents let sigData = - let _sigDataAttributes,sigDataResources = Driver.EncodeInterfaceData(tcConfig,tcGlobals,exportRemapping,generatedCcu,outfile,true) + let _sigDataAttributes, sigDataResources = Driver.EncodeInterfaceData(tcConfig, tcGlobals, exportRemapping, generatedCcu, outfile, true) [ for r in sigDataResources do let ccuName = GetSignatureDataResourceName r let bytes = @@ -1142,14 +1151,14 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig,tcGlobals,tcState:Tc | _ -> assert false; failwith "unreachable" yield (ccuName, bytes) ] - let autoOpenAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindStringAttribute tcGlobals tcGlobals.attrib_AutoOpenAttribute) - let ivtAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindStringAttribute tcGlobals tcGlobals.attrib_InternalsVisibleToAttribute) + let autoOpenAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_AutoOpenAttribute) + let ivtAttrs = topAttrs.assemblyAttrs |> List.choose (List.singleton >> TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_InternalsVisibleToAttribute) interface IRawFSharpAssemblyData with member __.GetAutoOpenAttributes(_ilg) = autoOpenAttrs member __.GetInternalsVisibleToAttributes(_ilg) = ivtAttrs member __.TryGetRawILModule() = None - member __.GetRawFSharpSignatureData(_m,_ilShortAssemName,_filename) = sigData - member __.GetRawFSharpOptimizationData(_m,_ilShortAssemName,_filename) = [ ] + member __.GetRawFSharpSignatureData(_m, _ilShortAssemName, _filename) = sigData + member __.GetRawFSharpOptimizationData(_m, _ilShortAssemName, _filename) = [ ] member __.GetRawTypeForwarders() = mkILExportedTypes [] // TODO: cross-project references with type forwarders member __.ShortAssemblyName = assemblyName member __.ILScopeRef = IL.ILScopeRef.Assembly ilAssemRef @@ -1159,8 +1168,8 @@ type RawFSharpAssemblyDataBackedByLanguageService (tcConfig,tcGlobals,tcState:Tc /// Manages an incremental build graph for the build of a single F# project -type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs, nonFrameworkResolutions, unresolvedReferences, tcConfig: TcConfig, projectDirectory, outfile, - assemblyName, niceNameGen: Ast.NiceNameGenerator, lexResourceManager, +type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInputs, nonFrameworkResolutions, unresolvedReferences, tcConfig: TcConfig, projectDirectory, outfile, + assemblyName, niceNameGen: Ast.NiceNameGenerator, lexResourceManager, sourceFiles, loadClosureOpt: LoadClosure option, keepAssemblyContents, keepAllBackgroundResolutions, maxTimeShareMilliseconds) = @@ -1172,12 +1181,12 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs let projectChecked = new Event() // Check for the existence of loaded sources and prepend them to the sources list if present. - let sourceFiles = tcConfig.GetAvailableLoadedSources() @ (sourceFiles |>List.map (fun s -> rangeStartup,s)) + let sourceFiles = tcConfig.GetAvailableLoadedSources() @ (sourceFiles |>List.map (fun s -> rangeStartup, s)) // Mark up the source files with an indicator flag indicating if they are the last source file in the project let sourceFiles = let flags, isExe = tcConfig.ComputeCanContainEntryPoint(sourceFiles |> List.map snd) - ((sourceFiles,flags) ||> List.map2 (fun (m,nm) flag -> (m,nm,(flag, isExe)))) + ((sourceFiles, flags) ||> List.map2 (fun (m, nm) flag -> (m, nm, (flag, isExe)))) let defaultTimeStamp = DateTime.Now @@ -1185,7 +1194,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs [ for (UnresolvedAssemblyReference(referenceText, _)) in unresolvedReferences do // Exclude things that are definitely not a file name if not(FileSystem.IsInvalidPathShim(referenceText)) then - let file = if FileSystem.IsPathRootedShim(referenceText) then referenceText else Path.Combine(projectDirectory,referenceText) + let file = if FileSystem.IsPathRootedShim(referenceText) then referenceText else Path.Combine(projectDirectory, referenceText) yield file for r in nonFrameworkResolutions do @@ -1193,7 +1202,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs let allDependencies = [| yield! basicDependencies - for (_,f,_) in sourceFiles do + for (_, f, _) in sourceFiles do yield f |] // The IncrementalBuilder needs to hold up to one item that needs to be disposed, which is the tcImports for the incremental @@ -1227,14 +1236,14 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs cache.GetFileTimeStamp filename // Deduplicate module names - let moduleNamesDict = Dictionary>() + let moduleNamesDict = Dictionary>() /// This is a build task function that gets placed into the build rules as the computation for a VectorMap /// /// Parse the given files and return the given inputs. This function is expected to be /// able to be called with a subset of sourceFiles and return the corresponding subset of /// parsed inputs. - let ParseTask ctok (sourceRange:range,filename:string,isLastCompiland) = + let ParseTask ctok (sourceRange:range, filename:string, isLastCompiland) = assertNotDisposed() DoesNotRequireCompilerThreadTokenAndCouldPossiblyBeMadeConcurrent ctok @@ -1244,11 +1253,11 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs try IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename) - let input = ParseOneInputFile(tcConfig,lexResourceManager, [], filename ,isLastCompiland,errorLogger,(*retryLocked*)true) + let input = ParseOneInputFile(tcConfig, lexResourceManager, [], filename , isLastCompiland, errorLogger, (*retryLocked*)true) fileParsed.Trigger (filename) let result = Option.map (DeduplicateParsedInputModuleName moduleNamesDict) input - result,sourceRange,filename,errorLogger.GetErrors () + result, sourceRange, filename, errorLogger.GetErrors () with exn -> System.Diagnostics.Debug.Assert(false, sprintf "unexpected failure in IncrementalFSharpBuild.Parse\nerror = %s" (exn.ToString())) failwith "last chance failure" @@ -1308,7 +1317,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs | Some loadClosure -> for inp in loadClosure.Inputs do for (err, isError) in inp.MetaCommandDiagnostics do - yield err,(if isError then FSharpErrorSeverity.Error else FSharpErrorSeverity.Warning) ] + yield err, (if isError then FSharpErrorSeverity.Error else FSharpErrorSeverity.Warning) ] let tcAcc = { tcGlobals=tcGlobals @@ -1333,7 +1342,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs | Some input, _sourceRange, filename, parseErrors-> IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBETypechecked filename) let capturingErrorLogger = CompilationErrorLogger("TypeCheckTask", tcConfig.errorSeverityOptions) - let errorLogger = GetErrorLoggerFilteringByScopedPragmas(false,GetScopedPragmasForInput(input),capturingErrorLogger) + let errorLogger = GetErrorLoggerFilteringByScopedPragmas(false, GetScopedPragmasForInput(input), capturingErrorLogger) let fullComputation = eventually { beforeFileChecked.Trigger (filename) @@ -1342,14 +1351,14 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs let sink = TcResultsSinkImpl(tcAcc.tcGlobals) let hadParseErrors = not (List.isEmpty parseErrors) - let! (tcEnvAtEndOfFile,topAttribs,typedImplFiles),tcState = + let! (tcEnvAtEndOfFile, topAttribs, typedImplFiles), tcState = TypeCheckOneInputEventually - ((fun () -> hadParseErrors || errorLogger.ErrorCount > 0), - tcConfig,tcAcc.tcImports, - tcAcc.tcGlobals, - None, - TcResultsSink.WithSink sink, - tcAcc.tcState,input) + ((fun () -> hadParseErrors || errorLogger.ErrorCount > 0), + tcConfig, tcAcc.tcImports, + tcAcc.tcGlobals, + None, + TcResultsSink.WithSink sink, + tcAcc.tcState, input) /// Only keep the typed interface files when doing a "full" build for fsc.exe, otherwise just throw them away let typedImplFiles = if keepAssemblyContents then typedImplFiles else [] @@ -1404,17 +1413,17 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs let finalAcc = tcStates.[tcStates.Length-1] // Finish the checking - let (_tcEnvAtEndOfLastFile,topAttrs,mimpls),tcState = + let (_tcEnvAtEndOfLastFile, topAttrs, mimpls), tcState = let results = tcStates |> List.ofArray |> List.map (fun acc-> acc.tcEnvAtEndOfFile, defaultArg acc.topAttribs EmptyTopAttrs, acc.typedImplFiles) - TypeCheckMultipleInputsFinish (results,finalAcc.tcState) + TypeCheckMultipleInputsFinish (results, finalAcc.tcState) let ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt = try - // TypeCheckClosedInputSetFinish fills in tcState.Ccu but in incremental scenarios we don't want this, + // TypeCheckClosedInputSetFinish fills in tcState.Ccu but in incremental scenarios we don't want this, // so we make this temporary here let oldContents = tcState.Ccu.Deref.Contents try - let tcState,tcAssemblyExpr = TypeCheckClosedInputSetFinish (mimpls,tcState) + let tcState, tcAssemblyExpr = TypeCheckClosedInputSetFinish (mimpls, tcState) // Compute the identity of the generated assembly based on attributes, options etc. // Some of this is duplicated from fsc.fs @@ -1428,9 +1437,9 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs with e -> errorRecoveryNoRange e None - let locale = TryFindStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyCultureAttribute") topAttrs.assemblyAttrs + let locale = TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyCultureAttribute") topAttrs.assemblyAttrs let assemVerFromAttrib = - TryFindStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyVersionAttribute") topAttrs.assemblyAttrs + TryFindFSharpStringAttribute tcGlobals (tcGlobals.FindSysAttrib "System.Reflection.AssemblyVersionAttribute") topAttrs.assemblyAttrs |> Option.bind (fun v -> try Some (parseILVersion v) with _ -> None) let ver = match assemVerFromAttrib with @@ -1443,11 +1452,11 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs // Assemblies containing type provider components can not successfully be used via cross-assembly references. // We return 'None' for the assembly portion of the cross-assembly reference let hasTypeProviderAssemblyAttrib = - topAttrs.assemblyAttrs |> List.exists (fun (Attrib(tcref,_,_,_,_,_,_)) -> tcref.CompiledRepresentationForNamedType.BasicQualifiedName = typeof.FullName) + topAttrs.assemblyAttrs |> List.exists (fun (Attrib(tcref, _, _, _, _, _, _)) -> tcref.CompiledRepresentationForNamedType.BasicQualifiedName = typeof.FullName) if tcState.CreatesGeneratedProvidedTypes || hasTypeProviderAssemblyAttrib then None else - Some (RawFSharpAssemblyDataBackedByLanguageService (tcConfig,tcGlobals,tcState,outfile,topAttrs,assemblyName,ilAssemRef) :> IRawFSharpAssemblyData) + Some (RawFSharpAssemblyDataBackedByLanguageService (tcConfig, tcGlobals, tcState, outfile, topAttrs, assemblyName, ilAssemRef) :> IRawFSharpAssemblyData) with e -> errorRecoveryNoRange e @@ -1475,7 +1484,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs // Inputs let fileNamesNode = InputVector "FileNames" - let referencedAssembliesNode = InputVector*(TimeStampCache -> CompilationThreadToken -> DateTime)> "ReferencedAssemblies" + let referencedAssembliesNode = InputVector*(TimeStampCache -> CompilationThreadToken -> DateTime)> "ReferencedAssemblies" // Build let stampedFileNamesNode = Vector.Stamp "SourceFileTimeStamps" StampFileNameTask fileNamesNode @@ -1568,11 +1577,11 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs let slotOfFile = builder.GetSlotOfFileName filename let result = match slotOfFile with - | (*first file*) 0 -> GetScalarResult(initialTcAccNode,partialBuild) - | _ -> GetVectorResultBySlot(tcStatesNode,slotOfFile-1,partialBuild) + | (*first file*) 0 -> GetScalarResult(initialTcAccNode, partialBuild) + | _ -> GetVectorResultBySlot(tcStatesNode, slotOfFile-1, partialBuild) match result with - | Some (tcAcc,timestamp) -> Some (PartialCheckResults.Create (tcAcc,timestamp)) + | Some (tcAcc, timestamp) -> Some (PartialCheckResults.Create (tcAcc, timestamp)) | _ -> None @@ -1591,14 +1600,14 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs match slotOfFile with | (*first file*) 0 -> let! build = IncrementalBuild.Eval cache ctok SavePartialBuild initialTcAccNode partialBuild - return GetScalarResult(initialTcAccNode,build) + return GetScalarResult(initialTcAccNode, build) | _ -> let! build = IncrementalBuild.EvalUpTo cache ctok SavePartialBuild (tcStatesNode, (slotOfFile-1)) partialBuild - return GetVectorResultBySlot(tcStatesNode,slotOfFile-1,build) + return GetVectorResultBySlot(tcStatesNode, slotOfFile-1, build) } match result with - | Some (tcAcc,timestamp) -> return PartialCheckResults.Create (tcAcc,timestamp) + | Some (tcAcc, timestamp) -> return PartialCheckResults.Create (tcAcc, timestamp) | None -> return! failwith "Build was not evaluated, expected the results to be ready after 'Eval' (GetCheckResultsBeforeSlotInProject)." } @@ -1617,13 +1626,13 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs cancellable { let cache = TimeStampCache(defaultTimeStamp) let! build = IncrementalBuild.Eval cache ctok SavePartialBuild finalizedTypeCheckNode partialBuild - match GetScalarResult(finalizedTypeCheckNode,build) with + match GetScalarResult(finalizedTypeCheckNode, build) with | Some ((ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, tcAcc), timestamp) -> - return PartialCheckResults.Create (tcAcc,timestamp), ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt + return PartialCheckResults.Create (tcAcc, timestamp), ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt | None -> // helpers to diagnose https://github.com/Microsoft/visualfsharp/pull/2460/ - let brname = match GetTopLevelExprByName(build,finalizedTypeCheckNode.Name) with ScalarBuildRule se ->se.Id | _ -> Id 0xdeadbeef - let data = (finalizedTypeCheckNode.Name, ((build.Results :> IDictionary<_,_>).Keys |> Seq.toArray), brname, build.Results.ContainsKey brname, build.Results.TryFind brname |> Option.map (function ScalarResult(sr) -> Some(sr.TryGetAvailable().IsSome) | _ -> None)) + let brname = match GetTopLevelExprByName(build, finalizedTypeCheckNode.Name) with ScalarBuildRule se ->se.Id | _ -> Id 0xdeadbeef + let data = (finalizedTypeCheckNode.Name, ((build.Results :> IDictionary<_, _>).Keys |> Seq.toArray), brname, build.Results.ContainsKey brname, build.Results.TryFind brname |> Option.map (function ScalarResult(sr) -> Some(sr.TryGetAvailable().IsSome) | _ -> None)) let msg = sprintf "Build was not evaluated, expected the results to be ready after 'Eval' (GetCheckResultsAndImplementationsForProject, data = %A)." data return! failwith msg } @@ -1635,17 +1644,17 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs member __.GetSlotOfFileName(filename:string) = // Get the slot of the given file and force it to build. - let CompareFileNames (_,f2,_) = + let CompareFileNames (_, f2, _) = let result = - String.Compare(filename,f2,StringComparison.CurrentCultureIgnoreCase)=0 - || String.Compare(FileSystem.GetFullPathShim(filename),FileSystem.GetFullPathShim(f2),StringComparison.CurrentCultureIgnoreCase)=0 + String.Compare(filename, f2, StringComparison.CurrentCultureIgnoreCase)=0 + || String.Compare(FileSystem.GetFullPathShim(filename), FileSystem.GetFullPathShim(f2), StringComparison.CurrentCultureIgnoreCase)=0 result - match TryGetSlotByInput(fileNamesNode,partialBuild,CompareFileNames) with + match TryGetSlotByInput(fileNamesNode, partialBuild, CompareFileNames) with | Some slot -> slot | None -> failwith (sprintf "The file '%s' was not part of the project. Did you call InvalidateConfiguration when the list of files in the project changed?" filename) member __.GetSlotsCount () = - let expr = GetExprByName(partialBuild,fileNamesNode) + let expr = GetExprByName(partialBuild, fileNamesNode) match partialBuild.Results.TryFind(expr.Id) with | Some (VectorResult vr) -> vr.Size | _ -> failwith "Failed to find sizes" @@ -1654,22 +1663,22 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs cancellable { let slotOfFile = builder.GetSlotOfFileName filename #if FCS_RETAIN_BACKGROUND_PARSE_RESULTS - match GetVectorResultBySlot(parseTreesNode,slotOfFile,partialBuild) with + match GetVectorResultBySlot(parseTreesNode, slotOfFile, partialBuild) with | Some (results, _) -> return results | None -> let! build = IncrementalBuild.EvalUpTo ctok SavePartialBuild (parseTreesNode, slotOfFile) partialBuild - match GetVectorResultBySlot(parseTreesNode,slotOfFile,build) with + match GetVectorResultBySlot(parseTreesNode, slotOfFile, build) with | Some (results, _) -> return results | None -> return! failwith "Build was not evaluated, expected the results to be ready after 'Eval' (GetParseResultsForFile)." #else let! results = cancellable { - match GetVectorResultBySlot(stampedFileNamesNode,slotOfFile,partialBuild) with + match GetVectorResultBySlot(stampedFileNamesNode, slotOfFile, partialBuild) with | Some (results, _) -> return results | None -> let cache = TimeStampCache(defaultTimeStamp) let! build = IncrementalBuild.EvalUpTo cache ctok SavePartialBuild (stampedFileNamesNode, slotOfFile) partialBuild - match GetVectorResultBySlot(stampedFileNamesNode,slotOfFile,build) with + match GetVectorResultBySlot(stampedFileNamesNode, slotOfFile, build) with | Some (results, _) -> return results | None -> return! failwith "Build was not evaluated, expected the results to be ready after 'Eval' (GetParseResultsForFile)." } @@ -1678,7 +1687,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs #endif } - member __.SourceFiles = sourceFiles |> List.map (fun (_,f,_) -> f) + member __.SourceFiles = sourceFiles |> List.map (fun (_, f, _) -> f) /// CreateIncrementalBuilder (for background type checking). Note that fsc.fs also /// creates an incremental builder used by the command line compiler. @@ -1749,15 +1758,15 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs let dllReferences = [for reference in tcConfigB.referencedDLLs do // If there's (one or more) resolutions of closure references then yield them all - match loadClosure.References |> List.tryFind (fun (resolved,_)->resolved=reference.Text) with - | Some (resolved,closureReferences) -> + match loadClosure.References |> List.tryFind (fun (resolved, _)->resolved=reference.Text) with + | Some (resolved, closureReferences) -> for closureReference in closureReferences do yield AssemblyReference(closureReference.originalReference.Range, resolved, None) | None -> yield reference] tcConfigB.referencedDLLs <- [] // Add one by one to remove duplicates dllReferences |> List.iter (fun dllReference -> - tcConfigB.AddReferencedAssemblyByPath(dllReference.Range,dllReference.Text)) + tcConfigB.AddReferencedAssemblyByPath(dllReference.Range, dllReference.Text)) tcConfigB.knownUnresolvedReferences <- loadClosure.UnresolvedReferences | None -> () @@ -1770,7 +1779,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs // Resolve assemblies and create the framework TcImports. This is done when constructing the // builder itself, rather than as an incremental task. This caches a level of "system" references. No type providers are // included in these references. - let! (tcGlobals,frameworkTcImports,nonFrameworkResolutions,unresolvedReferences) = frameworkTcImportsCache.Get(ctok, tcConfig) + let! (tcGlobals, frameworkTcImports, nonFrameworkResolutions, unresolvedReferences) = frameworkTcImportsCache.Get(ctok, tcConfig) // Note we are not calling errorLogger.GetErrors() anywhere for this task. // This is ok because not much can actually go wrong here. @@ -1798,9 +1807,9 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs yield Choice2Of2 pr, (fun (cache: TimeStampCache) ctok -> cache.GetProjectReferenceTimeStamp (pr, ctok)) ] let builder = - new IncrementalBuilder(tcGlobals,frameworkTcImports,nonFrameworkAssemblyInputs,nonFrameworkResolutions,unresolvedReferences, - tcConfig, projectDirectory, outfile, assemblyName, niceNameGen, - resourceManager, sourceFilesNew, loadClosureOpt, + new IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInputs, nonFrameworkResolutions, unresolvedReferences, + tcConfig, projectDirectory, outfile, assemblyName, niceNameGen, + resourceManager, sourceFilesNew, loadClosureOpt, keepAssemblyContents=keepAssemblyContents, keepAllBackgroundResolutions=keepAllBackgroundResolutions, maxTimeShareMilliseconds=maxTimeShareMilliseconds) diff --git a/src/fsharp/vs/Reactor.fs b/src/fsharp/vs/Reactor.fs index 7aa7d82c7eb..cc14a3d2fc0 100755 --- a/src/fsharp/vs/Reactor.fs +++ b/src/fsharp/vs/Reactor.fs @@ -35,7 +35,7 @@ type Reactor() = static let theReactor = Reactor() let mutable pauseBeforeBackgroundWork = pauseBeforeBackgroundWorkDefault - // We need to store the culture for the VS thread that is executing now, + // We need to store the culture for the VS thread that is executing now, // so that when the reactor picks up a thread from the threadpool we can set the culture let culture = new CultureInfo(CultureInfo.CurrentUICulture.Name) @@ -134,7 +134,7 @@ type Reactor() = try do! loop (None, None, false) with e -> - Debug.Assert(false,String.Format("unexpected failure in reactor loop {0}, restarting", e)) + Debug.Assert(false, String.Format("unexpected failure in reactor loop {0}, restarting", e)) } // [Foreground Mailbox Accessors] ----------------------------------------------------------- @@ -172,7 +172,7 @@ type Reactor() = async { let! ct = Async.CancellationToken let resultCell = AsyncUtil.AsyncResultCell<_>() - r.EnqueueOpPrim(userOpName, opName, opArg, ct, + r.EnqueueOpPrim(userOpName, opName, opArg, ct, op=(fun ctok -> let result = try @@ -181,7 +181,7 @@ type Reactor() = | ValueOrCancelled.Cancelled e -> AsyncUtil.AsyncCanceled e with e -> e |> AsyncUtil.AsyncException - resultCell.RegisterResult(result)), + resultCell.RegisterResult(result)), ccont=(fun () -> resultCell.RegisterResult (AsyncUtil.AsyncCanceled(OperationCanceledException(ct))) ) ) diff --git a/src/fsharp/vs/ServiceDeclarationLists.fs b/src/fsharp/vs/ServiceDeclarationLists.fs index e6c4a55ccd7..a36dc3ce69a 100644 --- a/src/fsharp/vs/ServiceDeclarationLists.fs +++ b/src/fsharp/vs/ServiceDeclarationLists.fs @@ -40,11 +40,24 @@ module EnvMisc3 = [] +/// Represents one parameter for one method (or other item) in a group. type FSharpMethodGroupItemParameter(name: string, canonicalTypeTextForSorting: string, display: layout, isOptional: bool) = + + /// The name of the parameter. member __.ParameterName = name + + /// A key that can be used for sorting the parameters, used to help sort overloads. member __.CanonicalTypeTextForSorting = canonicalTypeTextForSorting + + /// The structured representation for the parameter including its name, its type and visual indicators of other + /// information such as whether it is optional. member __.StructuredDisplay = display + + /// The text to display for the parameter including its name, its type and visual indicators of other + /// information such as whether it is optional. member __.Display = showL display + + /// Is the parameter optional member __.IsOptional = isOptional [] @@ -688,19 +701,37 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[], isForT -/// A single method for Intellisense completion -[] +/// Represents one method (or other item) in a method group. The item may represent either a method or +/// a single, non-overloaded item such as union case or a named function value. // Note: instances of this type do not hold any references to any compiler resources. +[] type FSharpMethodGroupItem(description: FSharpToolTipText, xmlDoc: FSharpXmlDoc, returnType: layout, parameters: FSharpMethodGroupItemParameter[], hasParameters: bool, hasParamArrayArg: bool, staticParameters: FSharpMethodGroupItemParameter[]) = + + /// The structured description representation for the method (or other item) member __.StructuredDescription = description + + /// The formatted description text for the method (or other item) member __.Description = Tooltips.ToFSharpToolTipText description + + /// The documentation for the item member __.XmlDoc = xmlDoc + + /// The The structured description representation for the method (or other item) member __.StructuredReturnTypeText = returnType + + /// The formatted type text for the method (or other item) member __.ReturnTypeText = showL returnType + + /// The parameters of the method in the overload set member __.Parameters = parameters + + /// Does the method support an arguments list? This is always true except for static type instantiations like TP<42,"foo">. member __.HasParameters = hasParameters + + /// Does the method support a params list arg? member __.HasParamArrayArg = hasParamArrayArg - // Does the type name or method support a static arguments list, like TP<42,"foo"> or conn.CreateCommand<42, "foo">(arg1, arg2)? + + /// Does the type name or method support a static arguments list, like TP<42,"foo"> or conn.CreateCommand<42, "foo">(arg1, arg2)? member __.StaticParameters = staticParameters diff --git a/src/fsharp/vs/ServiceDeclarationLists.fsi b/src/fsharp/vs/ServiceDeclarationLists.fsi index 4b37270d23a..1ed6e5d4e11 100644 --- a/src/fsharp/vs/ServiceDeclarationLists.fsi +++ b/src/fsharp/vs/ServiceDeclarationLists.fsi @@ -27,25 +27,37 @@ type internal FSharpDeclarationListItem = #endif /// Get the display name for the declaration. member Name : string + /// Get the name for the declaration as it's presented in source code. member NameInCode : string + /// Get the description text for the declaration. Computing this property may require using compiler /// resources and may trigger execution of a type provider method to retrieve documentation. /// /// May return "Loading..." if timeout occurs member StructuredDescriptionText : FSharpStructuredToolTipText + member DescriptionText : FSharpToolTipText /// Get the description text, asynchronously. Never returns "Loading...". member StructuredDescriptionTextAsync : Async + member DescriptionTextAsync : Async + member Glyph : FSharpGlyph + member Accessibility : FSharpAccessibility option + member Kind : CompletionItemKind + member IsOwnMember : bool + member MinorPriority : int + member FullName : string + member IsResolved : bool + member NamespaceToOpen : string option @@ -59,13 +71,18 @@ type FSharpDeclarationListInfo = #else type internal FSharpDeclarationListInfo = #endif + member Items : FSharpDeclarationListItem[] + member IsForType : bool + member IsError : bool // Implementation details used by other code in the compiler static member internal Create : infoReader:InfoReader * m:range * denv:DisplayEnv * getAccessibility:(Item -> FSharpAccessibility option) * items:CompletionItem list * reactor:IReactorOperations * currentNamespace:string[] option * isAttributeApplicationContex:bool * checkAlive:(unit -> bool) -> FSharpDeclarationListInfo + static member internal Error : message:string -> FSharpDeclarationListInfo + static member Empty : FSharpDeclarationListInfo /// Represents one parameter for one method (or other item) in a group. diff --git a/src/fsharp/vs/ServiceParamInfoLocations.fs b/src/fsharp/vs/ServiceParamInfoLocations.fs index 0150222b0ba..987d10c2de7 100755 --- a/src/fsharp/vs/ServiceParamInfoLocations.fs +++ b/src/fsharp/vs/ServiceParamInfoLocations.fs @@ -34,7 +34,7 @@ module internal NoteworthyParamInfoLocationsImpl = let isStaticArg a = match a with | SynType.StaticConstant _ | SynType.StaticConstantExpr _ | SynType.StaticConstantNamed _ -> true - | SynType.LongIdent _ -> true // NOTE: this is not a static constant, but it is a prefix of incomplete code, e.g. "TP<42,Arg3" is a prefix of "TP<42,Arg3=6>" and Arg3 shows up as a LongId + | SynType.LongIdent _ -> true // NOTE: this is not a static constant, but it is a prefix of incomplete code, e.g. "TP<42, Arg3" is a prefix of "TP<42, Arg3=6>" and Arg3 shows up as a LongId | _ -> false /// Dig out an identifier from an expression that used in an application @@ -42,8 +42,8 @@ module internal NoteworthyParamInfoLocationsImpl = // we found it, dig out ident match synExpr with | SynExpr.Ident(id) -> Some ([id.idText], id.idRange) - | SynExpr.LongIdent(_, LongIdentWithDots(lid,_), _, lidRange) - | SynExpr.DotGet(_, _, LongIdentWithDots(lid,_), lidRange) -> Some (pathOfLid lid, lidRange) + | SynExpr.LongIdent(_, LongIdentWithDots(lid, _), _, lidRange) + | SynExpr.DotGet(_, _, LongIdentWithDots(lid, _), lidRange) -> Some (pathOfLid lid, lidRange) | SynExpr.TypeApp(synExpr, _, _synTypeList, _commas, _, _, _range) -> digOutIdentFromFuncExpr synExpr | _ -> None @@ -53,30 +53,30 @@ module internal NoteworthyParamInfoLocationsImpl = let digOutIdentFromStaticArg synType = match synType with - | SynType.StaticConstantNamed(SynType.LongIdent(LongIdentWithDots([id],_)),_,_) -> Some id.idText - | SynType.LongIdent(LongIdentWithDots([id],_)) -> Some id.idText // NOTE: again, not a static constant, but may be a prefix of a Named in incomplete code + | SynType.StaticConstantNamed(SynType.LongIdent(LongIdentWithDots([id], _)), _, _) -> Some id.idText + | SynType.LongIdent(LongIdentWithDots([id], _)) -> Some id.idText // NOTE: again, not a static constant, but may be a prefix of a Named in incomplete code | _ -> None let getNamedParamName e = match e with // f(x=4) - | SynExpr.App(ExprAtomicFlag.NonAtomic, _, - SynExpr.App(ExprAtomicFlag.NonAtomic, true, + | SynExpr.App(ExprAtomicFlag.NonAtomic, _, + SynExpr.App(ExprAtomicFlag.NonAtomic, true, SynExpr.Ident op, SynExpr.Ident n, - _range), + _range), _, _) when op.idText="op_Equality" -> Some n.idText // f(?x=4) - | SynExpr.App(ExprAtomicFlag.NonAtomic, _, - SynExpr.App(ExprAtomicFlag.NonAtomic, true, + | SynExpr.App(ExprAtomicFlag.NonAtomic, _, + SynExpr.App(ExprAtomicFlag.NonAtomic, true, SynExpr.Ident op, - SynExpr.LongIdent(true(*isOptional*),LongIdentWithDots([n],_),_ref,_lidrange), _range), + SynExpr.LongIdent(true(*isOptional*), LongIdentWithDots([n], _), _ref, _lidrange), _range), _, _) when op.idText="op_Equality" -> Some n.idText | _ -> None let getTypeName(synType) = match synType with - | SynType.LongIdent(LongIdentWithDots(ids,_)) -> ids |> pathOfLid + | SynType.LongIdent(LongIdentWithDots(ids, _)) -> ids |> pathOfLid | _ -> [""] // TODO type name for other cases, see also unit test named "ParameterInfo.LocationOfParams.AfterQuicklyTyping.CallConstructorViaLongId.Bug94333" let handleSingleArg traverseSynExpr (pos, synExpr, parenRange, rpRangeOpt : _ option) = @@ -101,19 +101,19 @@ module internal NoteworthyParamInfoLocationsImpl = match inner with | None -> if AstTraversal.rangeContainsPosEdgesExclusive parenRange pos then - let commasAndCloseParen = ((synExprList,commaRanges@[parenRange]) ||> List.map2 (fun e c -> c.End, getNamedParamName e)) + let commasAndCloseParen = ((synExprList, commaRanges@[parenRange]) ||> List.map2 (fun e c -> c.End, getNamedParamName e)) let r = Found (parenRange.Start, commasAndCloseParen, rpRangeOpt.IsSome) r, None else NotFound, None | _ -> NotFound, None - | SynExprParen(SynExprParen(SynExpr.Tuple(_,_,_),_,_,_) as synExpr, _, rpRangeOpt, parenRange) -> // f((x,y)) is special, single tuple arg - handleSingleArg traverseSynExpr (pos,synExpr,parenRange,rpRangeOpt) + | SynExprParen(SynExprParen(SynExpr.Tuple(_, _, _), _, _, _) as synExpr, _, rpRangeOpt, parenRange) -> // f((x, y)) is special, single tuple arg + handleSingleArg traverseSynExpr (pos, synExpr, parenRange, rpRangeOpt) // dig into multiple parens - | SynExprParen(SynExprParen(_,_,_,_) as synExpr, _, _, _parenRange) -> - let r,_cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr + | SynExprParen(SynExprParen(_, _, _, _) as synExpr, _, _, _parenRange) -> + let r, _cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr r, None | SynExprParen(synExpr, _lpRange, rpRangeOpt, parenRange) -> // single argument @@ -146,18 +146,18 @@ module internal NoteworthyParamInfoLocationsImpl = - let traverseInput(pos,parseTree) = + let traverseInput(pos, parseTree) = - AstTraversal.Traverse(pos,parseTree, { new AstTraversal.AstVisitorBase<_>() with + AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with member this.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = let expr = expr // fix debug locals match expr with - // new LID(...) and error recovery of these + // new LID(...) and error recovery of these | SynExpr.New(_, synType, synExpr, _range) -> - let constrArgsResult,cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr - match constrArgsResult,cacheOpt with - | Found(parenLoc,args,isThereACloseParen), _ -> + let constrArgsResult, cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr + match constrArgsResult, cacheOpt with + | Found(parenLoc, args, isThereACloseParen), _ -> let typeName = getTypeName synType Some (FSharpNoteworthyParamInfoLocations(typeName, synType.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd)) | NotFound, Some cache -> @@ -176,7 +176,7 @@ module internal NoteworthyParamInfoLocationsImpl = if AstTraversal.rangeContainsPosEdgesExclusive typeArgsm pos then // We found it, dig out ident match digOutIdentFromFuncExpr synExpr with - | Some(lid,lidRange) -> Some (FSharpNoteworthyParamInfoLocations(lid, lidRange, op.idRange.Start, [ wholem.End ], false, [])) + | Some(lid, lidRange) -> Some (FSharpNoteworthyParamInfoLocations(lid, lidRange, op.idRange.Start, [ wholem.End ], false, [])) | None -> None else None @@ -189,12 +189,12 @@ module internal NoteworthyParamInfoLocationsImpl = | Some _ -> fResult | _ -> // Search the argument - let xResult,cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr2 - match xResult,cacheOpt with - | Found(parenLoc,args,isThereACloseParen),_ -> + let xResult, cacheOpt = searchSynArgExpr traverseSynExpr pos synExpr2 + match xResult, cacheOpt with + | Found(parenLoc, args, isThereACloseParen), _ -> // We found it, dig out ident match digOutIdentFromFuncExpr synExpr with - | Some(lid,lidRange) -> + | Some(lid, lidRange) -> assert(isInfix = (posLt parenLoc lidRange.End)) if isInfix then // This seems to be an infix operator, since the start of the argument is a position earlier than the end of the long-id being applied to it. @@ -206,7 +206,7 @@ module internal NoteworthyParamInfoLocationsImpl = | NotFound, Some cache -> cache | _ -> traverseSynExpr synExpr2 - // ID and error recovery of these + // ID and error recovery of these | SynExpr.TypeApp(synExpr, openm, tyArgs, commas, closemOpt, _, wholem) -> match traverseSynExpr synExpr with | Some _ as r -> r @@ -221,9 +221,9 @@ module internal NoteworthyParamInfoLocationsImpl = | _ -> defaultTraverse expr - member this.VisitTypeAbbrev(tyAbbrevRhs,_m) = + member this.VisitTypeAbbrev(tyAbbrevRhs, _m) = match tyAbbrevRhs with - | SynType.App(SynType.LongIdent(LongIdentWithDots(lid,_) as lidwd), Some(openm), args, commas, closemOpt, _pf, wholem) -> + | SynType.App(SynType.LongIdent(LongIdentWithDots(lid, _) as lidwd), Some(openm), args, commas, closemOpt, _pf, wholem) -> let lidm = lidwd.Range let betweenTheBrackets = mkRange wholem.FileName openm.Start wholem.End if AstTraversal.rangeContainsPosEdgesExclusive betweenTheBrackets pos && args |> List.forall isStaticArg then @@ -241,9 +241,9 @@ module internal NoteworthyParamInfoLocationsImpl = let inheritm = mkRange m.FileName m.Start m.End if AstTraversal.rangeContainsPosEdgesExclusive inheritm pos then // inherit ty(expr) --- treat it like an application (constructor call) - let xResult,_cacheOpt = searchSynArgExpr defaultTraverse pos expr + let xResult, _cacheOpt = searchSynArgExpr defaultTraverse pos expr match xResult with - | Found(parenLoc,args,isThereACloseParen) -> + | Found(parenLoc, args, isThereACloseParen) -> // we found it, dig out ident let typeName = getTypeName ty let r = FSharpNoteworthyParamInfoLocations(typeName, ty.Range, parenLoc, args |> List.map fst, isThereACloseParen, args |> List.map snd) @@ -253,12 +253,12 @@ module internal NoteworthyParamInfoLocationsImpl = }) type FSharpNoteworthyParamInfoLocations with - static member Find(pos,parseTree) = - match traverseInput(pos,parseTree) with + static member Find(pos, parseTree) = + match traverseInput(pos, parseTree) with | Some nwpl as r -> #if DEBUG let ranges = nwpl.LongIdStartLocation :: nwpl.LongIdEndLocation :: nwpl.OpenParenLocation :: (nwpl.TupleEndLocations |> Array.toList) - let sorted = ranges |> List.sortWith (fun a b -> posOrder.Compare(a,b)) |> Seq.toList + let sorted = ranges |> List.sortWith (fun a b -> posOrder.Compare(a, b)) |> Seq.toList assert(ranges = sorted) #else ignore nwpl diff --git a/src/fsharp/vs/ServiceParamInfoLocations.fsi b/src/fsharp/vs/ServiceParamInfoLocations.fsi index 137ae4ad9c4..d72e6330b74 100755 --- a/src/fsharp/vs/ServiceParamInfoLocations.fsi +++ b/src/fsharp/vs/ServiceParamInfoLocations.fsi @@ -10,22 +10,35 @@ namespace Microsoft.FSharp.Compiler.SourceCodeServices open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler.Range +/// Represents the locations relevant to activating parameter info in an IDE [] #if COMPILER_PUBLIC_API type FSharpNoteworthyParamInfoLocations = #else type internal FSharpNoteworthyParamInfoLocations = #endif + + /// The text of the long identifier prior to the open-parentheses member LongId : string list + + /// The start location of long identifier prior to the open-parentheses member LongIdStartLocation : pos + + /// The end location of long identifier prior to the open-parentheses member LongIdEndLocation : pos + + /// The location of the open-parentheses member OpenParenLocation : pos - /// locations of commas and close parenthesis (or, last char of last arg, if no final close parenthesis) + + /// The locations of commas and close parenthesis (or, last char of last arg, if no final close parenthesis) member TupleEndLocations : pos[] - /// false if either this is a call without parens "f x" or the parser recovered as in "f(x,y" + + /// Is false if either this is a call without parens "f x" or the parser recovered as in "f(x,y" member IsThereACloseParen : bool - /// empty or a name if an actual named parameter; f(0,a=4,?b=None) would be [|None; Some "a"; Some "b"|] + + /// Either empty or a name if an actual named parameter; f(0,a=4,?b=None) would be [|None; Some "a"; Some "b"|] member NamedParamNames : string option [] + /// Find the information about parameter info locations at a particular source location static member Find : pos * Ast.ParsedInput -> FSharpNoteworthyParamInfoLocations option