-
Notifications
You must be signed in to change notification settings - Fork 790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Project References for net sdk projects. #3653
Conversation
eaf95ee
to
216dca9
Compare
@dotnet-bot test Windows_NT Release_ci_part2 Build please |
I've tried to review this several times, and it's a little dense for me to follow - let's talk about it together on Tuesday. |
Sure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes needed, see comments
@@ -126,6 +122,8 @@ type internal FSharpProjectOptionsManager | |||
member this.ClearInfoForSingleFileProject(projectId) = | |||
singleFileProjectTable.TryRemove(projectId) |> ignore | |||
|
|||
member __.CommandLineOptions with get() = commandLineOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can (and should) remove with get()
to be idiomatic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I need to work on my F# programming skillz :-)
Some options | ||
else | ||
Some { ProjectFileName = options.ProjectFileName | ||
SourceFiles = if sourcePaths.Length = 0 then options.SourceFiles else sourcePaths |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already know from the preceding condition that sourcePaths.Lengths = 0
is false, you can simplify this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other line is an 'or' || so I don't necessarily know that it is 0.
if sourcePaths.Length = 0 || otherOptions.Length = 0 then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
@@ -183,7 +181,23 @@ type internal FSharpProjectOptionsManager | |||
/// Get the options for a project | |||
member this.TryGetOptionsForProject(projectId: ProjectId) = | |||
match projectTable.TryGetValue(projectId) with | |||
| true, ((_referencedProjects, options), _) -> Some options |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned by this change. the whole point of TryGetOptionsForProject
and projectTable
is to maintain the canonical FSharpProjectOptions
object for the project so it doesn't need to be recomputed - and FCS can use Stamp
to tell if the project options of dependent projects have changed. For example, each time you make a new options object you should bump Stamp
.
But with this change, the options stored in projectTable
are no longer canonical and up-to-date - instead you have to go through this routine to get the latest options.
It would be better to update options entry in projectTable
either here (on-demand) or at some earlier point when we know that the CommandLineOptions
/sourcePaths
/otherOptions
results change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that failing to keep the projectTable
canonical may have correctness of performance effects on incorrect or recomputation of project options.
@@ -411,13 +367,20 @@ type | |||
|
|||
let optionsAssociation = ConditionalWeakTable<IWorkspaceProjectContext, string[]>() | |||
|
|||
member private this.OnProjectAdded(projectId:ProjectId, _newSolution:Solution) = projectInfoManager.UpdateProjectInfoWithProjectId(projectId, "OnProjectAdded") | |||
member private this.OnProjectAdded(projectId:ProjectId, _newSolution:Solution) = projectInfoManager.UpdateProjectInfoWithProjectId(projectId, "OnProjectAdded") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If _newSolution
is unused then why not remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect that we will be using eventually. It's just not necessary right now.
| WorkspaceChangeKind.ProjectAdded -> this.OnProjectAdded(args.ProjectId, args.NewSolution) | ||
| WorkspaceChangeKind.ProjectChanged -> this.OnProjectChanged(args.ProjectId, args.NewSolution) | ||
| WorkspaceChangeKind.ProjectReloaded -> this.OnProjectReloaded(args.ProjectId, args.NewSolution) | ||
// | WorkspaceChangeKind.ProjectRemoved -> this.OnProjectRemoved(args.ProjectId, args.NewSolution) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's up with Removed? Please add a comment as to what needs to be done here
@@ -101,7 +109,75 @@ type private ProjectSiteOfSingleFile(sourceFile) = | |||
override this.AssemblyReferences() = [||] | |||
|
|||
override x.ToString() = sprintf "ProjectSiteOfSingleFile(%s)" sourceFile | |||
|
|||
type CommandLineOptions (isEmpty:bool) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a ///
comment explaining what this is. Always...
|
||
new () = CommandLineOptions(false) | ||
|
||
member __.GetOptionsWithProjectId(projectId:ProjectId) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add ///
comments on all new members
type CommandLineOptions (isEmpty:bool) = | ||
|
||
let commandLineOptions = new ConcurrentDictionary<ProjectId, string[]*string[]*string[]>() | ||
static let emptyCommandLineOptions = lazy new CommandLineOptions(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no point in making such a trivial object allocation lazy - just remove the ``lazy`
|
||
static member Empty with get () = emptyCommandLineOptions.Value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the with get()
member __.GetOptionsWithProjectId(projectId:ProjectId) = | ||
match commandLineOptions.TryGetValue projectId with | ||
| true, value -> value | ||
| _ -> [||], [||], [||] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should return a None
on this branch
Hmm seems as if I have broken p2p references :-( |
@dotnet-bot test Windows_NT Release_ci_part1 Build |
@@ -207,8 +207,9 @@ type internal FSharpProjectOptionsManager | |||
match hier with | |||
| h when (h.IsCapabilityMatch("CPS")) -> | |||
let project = workspace.CurrentSolution.GetProject(projectId) | |||
let siteProvider = provideProjectSiteProvider(workspace, project, serviceProvider, Some projectOptionsTable) | |||
this.UpdateProjectInfo(tryGetOrCreateProjectId, projectId, siteProvider.GetProjectSite(), userOpName) | |||
if project <> null then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is x = null
or x <> null
strictly less efficient than a pattern match or isNull
/not isNull
call? Not sure if my knowledge here is rusty or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC 'x = null' can throw NullReferenceException at runtime when x is null and the compiler thinks that it cannot be null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isNotNull x is probably the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm!!! isNotNull is internal: https://github.com/Microsoft/visualfsharp/blob/e6d46b9f56295aa70889ebff59cc0c6f0144a3ce/src/fsharp/FSharp.Core/prim-types.fs#L3324
It came in after we shutdown for 4.1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it changed fsharp.core surface area when I added it. And my changes where rolled back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other words: it was public for a week or so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See fsharp/fslang-suggestions#99 (comment)
... we have a design rule not to put "NotXYZ" predicates in the core library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dsyme ahh well this doen't fall under that rule because it is:
isNotNull :-)
It is a decent api we should make it public for FSharp.Core 4.3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The design rule is clear both for F# and for .NET - we don't put negative "not" predicates in our libraries. It is a slippery slope and we should not go down it. Just use not (isNull x)
.
If that's not satisfactory we would be much better off putting effort into fsharp/fslang-suggestions#569 to eventually allow !isNull x
So this doesn't work unless the project has been pre-built for dotnet sdk projects I still need to figure that out. |
This doesn't work for me if the libraries are pre-built either. This is on 15.5 Preview 1 bits. Should I be testing against something else? |
| _ -> () | ||
| None -> () | ||
| None -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is dubious - your new code is only being hit when solutionService
is None
, which should never happen?
// not the intermediate output directory. | ||
// so as a Giant kludge transform obj to bin | ||
// ====================================================================== | ||
yield Some projectId, project.FilePath, outputPath.Replace(@"\obj\", @"\bin\"), siteProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it won't that's why the 'Hack!!!!!!' I think I am pretty sure I need the project System to have set this value. Or I should figure out why FCS needs it ... which is probably more of a winner here.
// project.OutputFilePath does not have a value at this point ... | ||
// so calculate one by peeking at the command line options ... --out: | ||
// ====================================================================== | ||
match projectOptionsTable with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why this works. According to what @davkean was telling me yesterday, at the point where the OutputFilePath is still null, we shouldn't have any options yet, just the source files because it comes from evaluation only...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kevinpi. Well the command line options from designtimebuild have been received at this point.
f6b435c
to
22da6d8
Compare
22da6d8
to
68f4187
Compare
Approach
Addresses #3571