-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Code fix to add unsafe option to C# project #25875
Conversation
Also note that undo does not work for this just as it doesn't work for UpgradeProject. Implementing it is not trivial because when invoking the code fix, we change options in all configurations and undoing would require only reverting the configurations that were actually changed. But this should still be tracked in an issue and fixed later. |
src/Features/CSharp/Portable/UnsafeProject/CSharpUnsafeProjectCodeFixProvider.cs
Outdated
Show resolved
Hide resolved
break; | ||
|
||
case LanguageNames.VisualBasic: | ||
throw new InvalidOperationException(ServicesVSResources.This_workspace_does_not_support_updating_Visual_Basic_compilation_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.
@jasonmalinowski can you review thei method.
src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs
Show resolved
Hide resolved
&& !this.CanApplyChange(ApplyChangesKind.ChangeCompilationOptions)) | ||
&& !this.CanApplyChange(ApplyChangesKind.ChangeCompilationOptions) | ||
&& !this.CanApplyCompilationOptionChange( | ||
projectChanges.OldProject.CompilationOptions, projectChanges.NewProject.CompilationOptions, projectChanges.NewProject)) | ||
{ |
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.
Here you can see that if CanApplyChange returns false but CanApplyCompilationOptionChange returns true, this check passes. If CanApplyChange returns true, it passes regardless of what CanApplyCompilationOptionChange
returns. Therefore VisualStudioWorkspace returning true for CanApplyChange(ApplyChangesKind.ChangeParseOptions) and CanApplyChange(ApplyChangesKind.ChangeCompilationOptions) must be wrong, since it doesn't support changing arbitrary 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.
@jcouv It looks like you wrote this. Could you clarify what the intent was here? Thanks
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 mean the equivalent code for parse options below.
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.
Hum, this does seem wrong. I would think that both checks should be:
if (<options changed>&& (!CanApplyChange() || !CanApplyXyzOptionChange()) ...
I'll let @jasonmalinowski confirm, since I'm not very familiar with workspaces.
In reply to: 178513336 [](ancestors = 178513336)
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 not very familiar with workspaces
but you created this API 😄
I'll mention the two options again. This API could be interpreted in 2 ways:
CanApplyChange(ApplyChangesKind.ChangeParseOptions)
returning true means the workspace is able to change some parse options - you don't know whether it can handle the option you want until you additionally callCanApplyParseOptionChange
. So in this scenario,CanApplyChange
really basically tells you nothing about what you can actually do. This might have been the original intent (but implemented incorrectly).CanApplyChange(ApplyChangesKind.ChangeParseOptions)
returning true means the workspace supports changing parse options, period. Any kind of change, and you can count on that. Now it may also support changing some specific options even if this returns false. If you checkCanApplyParseOptionChange
, you might find out that is the case. This is the existing implementation.
@jcouv I see you're suggesting we should really have the first option. I think both of them make sense, but if we go with first, then the default value of CanApplyCompilationChange
being false is wrong and would be a breaking change. Basically, until now, if you get true from CanApplyChange(ApplyChangesKind.ChangeCompilationOptions)
you know the workspace supports changing any compilation options, but if we implement this the way you're suggesting, the new meaning would be "no, this actually doesn't supports changing compilation options at all because CanApplyCompilationChange
still always returns false". If we go with number 1, the default implementation should return true. But there's also a problem that the existing implementation of CanApplyParseChange
returns false. Meh :-/
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.
Thanks. It would make sense if this API was indeed public (and the default value of the precise check is change to true
so we don't break existing implementors who use the coarse check as the only one). But I don't think I'd want to add a public API here, so then is it ok to leave that for later? What do you suggest I do about this now, leave everything as is, since things were equally broken before? Or would it not hurt this PR too much to do that here even with all the work required to review such a 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.
I would either do nothing and leave all the brokeness as is, or make the API public and do the right thing. [insert Yoda meme here]
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 I did do that work, do you think it would be an acceptable change to change the default value of CanApplyParseOptionChange to true? I think that's the right value because anyone who doesn't implement that and only implements CanApplyChange expects users to be able to change those options. In fact if I kept these as returning false and fixed the code checking this, it would be a much bigger breaking 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.
Actually, default behavior should probably be to call CanApplyChange(ApplyChangesKind.ChangeParseOptions). That way workspaces that said no also say no from the new API, workspaces that say yes get the default "anything goes" which is the correct representation, and overriders get the right thing anyways.
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, I was just thinking that's a little silly/redundant if the proper check is to always do CanApplyChange && CanApplyParseOptionChange anyway, but that works too I suppose. I can't think of any problems with that.
Or is the contract of this API supposed to be that CanApplyParseOptionChange is a sufficient check on its own?
@@ -17,3 +17,4 @@ const Microsoft.CodeAnalysis.Classification.ClassificationTypeNames.ParameterNam | |||
const Microsoft.CodeAnalysis.Classification.ClassificationTypeNames.PropertyName = "property name" -> string | |||
static Microsoft.CodeAnalysis.ProjectInfo.Create(Microsoft.CodeAnalysis.ProjectId id, Microsoft.CodeAnalysis.VersionStamp version, string name, string assemblyName, string language, string filePath = null, string outputFilePath = null, Microsoft.CodeAnalysis.CompilationOptions compilationOptions = null, Microsoft.CodeAnalysis.ParseOptions parseOptions = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> documents = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.ProjectReference> projectReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.MetadataReference> metadataReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference> analyzerReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> additionalDocuments = null, bool isSubmission = false, System.Type hostObjectType = null, string outputRefFilePath = null) -> Microsoft.CodeAnalysis.ProjectInfo | |||
static Microsoft.CodeAnalysis.ProjectInfo.Create(Microsoft.CodeAnalysis.ProjectId id, Microsoft.CodeAnalysis.VersionStamp version, string name, string assemblyName, string language, string filePath, string outputFilePath, Microsoft.CodeAnalysis.CompilationOptions compilationOptions, Microsoft.CodeAnalysis.ParseOptions parseOptions, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> documents, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.ProjectReference> projectReferences, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.MetadataReference> metadataReferences, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference> analyzerReferences, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> additionalDocuments, bool isSubmission, System.Type hostObjectType) -> Microsoft.CodeAnalysis.ProjectInfo | |||
virtual Microsoft.CodeAnalysis.Workspace.CanApplyCompilationOptionChange(Microsoft.CodeAnalysis.CompilationOptions oldOptions, Microsoft.CodeAnalysis.CompilationOptions newOptions, Microsoft.CodeAnalysis.Project project) -> 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.
📝 New public API modeled after CanApplyParseOptionChange
Bad news. This doesn't work with the new project system :( AllowUnsafeBlocks throws Edit: ➡️ Fixed by using |
I think the problem was that |
src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs
Outdated
Show resolved
Hide resolved
@Neme12 looks like the test Note: no need to wait for me to look here. The Mono test failures show up in the Test tab just like all the other ones. 😄 |
I'd say once we have a green roslyn-CI and @sharwell can confirm the roslyn-integration-CI isn't a problem, I'm OK with the merge. We may have some trouble figuring out which branch this has to be merged into though, but that's something we have to do on our side. |
@sharwell Do you know why the integration tests are failing? Is it safe to ignore? |
@jasonmalinowski There was a green Windows_VisualStudio_Integration_Tests release run now. Debug timed out, but not because of my tests. If you look at the tests tab, show tests with all outcomes and search for "CPSProject" and "LegacyProject", you can see that all 6 of them passed. Are you happy with merging now? |
@jasonmalinowski Is there anything preventing this from going in? |
@sharwell Can you confirm this looks good from your perspective? |
(and @sharwell by that I just mean whether the integration tests meet expectations) |
@Neme12 You're OK if I push to your branch to resolve the merge conflict? |
@jasonmalinowski Yes, feel free to do that. Thanks. |
@jasonmalinowski Can you please rerun Linux_Test coreclr? |
@sharwell confirmed privately that the integration test issues seem unrelated. |
Thanks. 🎉 Finally I get some closure here 😄 |
Congrats! I actually ran into this a couple of days ago as part of a discussion around fixed size buffers. And i was sad this didn't work! |
Me too! |
Talk to @YairHalberstadt. He has some good ideas on how to deal with closures. |
By saying we support ChangeCompilationOptions and ChangeParseOptions, this meant that we supported _all_ possible changes; if you changed an option in a code fix we didn't actually support updating your project file for, we'd still let the code fix apply and just not update your project file. That's not terribly great. Returning false for CanApplyChanges then means the workspace calls the more precise methods that actually check the specific option. I think this means all the specific checking done in dotnet#25875 never actually worked.
Fixes #25722
Fixes #23342
Partially fixes #22433 / dotnet/project-system#2732 (only for CPS projects)
Things I'd appreciate some feedback on:#resolvedTagging @jcouv @CyrusNajmabadi