-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Do not go back to Workspace in SyntaxEditor #62910
Do not go back to Workspace in SyntaxEditor #62910
Conversation
src/Workspaces/Core/Portable/Workspace/Solution/AdditionalDocumentState.cs
Outdated
Show resolved
Hide resolved
{ | ||
} | ||
|
||
internal SolutionState State => _state; | ||
|
||
internal int WorkspaceVersion => _state.WorkspaceVersion; | ||
|
||
internal SolutionServices Services => _state.Services; | ||
public HostWorkspaceServices Services => _state.Services; |
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 this intended to be public? Need API review approval if 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.
yes. this will go through API review.
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.
API review tracked through #62914
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.
Approved pending API review approval for the public API. Or you could change the accessibility back to internal for now and merge this before API review.
so it can't currently be internal, because it's accessed in CodeStyle layer. I think we'll run this like several high confidence APIs. Merge in, and get approval on thursday. If anything needs to change, we can do so then. Are you ok with that @tmat ? |
@@ -176,7 +172,7 @@ public SolutionState WithNewWorkspace(Workspace workspace, int workspaceVersion) | |||
/// <summary> | |||
/// The Workspace this solution is associated with. | |||
/// </summary> | |||
public Workspace Workspace => _solutionServices.Workspace; | |||
public Workspace Workspace => Services.Workspace; |
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.
yup.
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.
Not merging this. Feedback from @jasonmalinowski is making us reconsider this. |
Ok, i changed the approach we're taking here to use a new immutable type that doesn't expose the workspace. Please take a look |
...s/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs
Outdated
Show resolved
Hide resolved
…UseConditionalExpressionCodeFixProvider.cs
@@ -48,7 +48,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) | |||
public static async Task<Document> FixAllAsync(Document document, ImmutableArray<Diagnostic> diagnostics, CodeActionOptionsProvider codeActionOptionsProvider, CancellationToken cancellationToken) | |||
{ | |||
var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | |||
var editor = new SyntaxEditor(root, document.Project.Solution.Workspace.Services); | |||
var editor = document.GetSyntaxEditor(root); |
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.
these are at a layer (code_style) that cannot access internal apis. So while the API is in flux and hasn't been fully signed off on, this code has to go through an indirection (an extension method) so it can do the right thing in Roslyn vs CodeStyle.
...s/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs
Outdated
Show resolved
Hide resolved
…UseConditionalExpressionCodeFixProvider.cs
…usNajmabadi/roslyn into syntaxEditorWorkspaceService
@@ -115,7 +115,7 @@ private async Task<Document> ApplyAsync(Document document, TTypeDeclarationSynta | |||
var syntaxRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | |||
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); | |||
|
|||
var editor = new SyntaxEditor(syntaxRoot, document.Project.Solution.Workspace.Services); | |||
var editor = new SyntaxEditor(syntaxRoot, document.Project.Solution.Services); |
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.
this code isn't shared in the CODE_STYLE layer. so it wasn't necessary. a lot of the changes were done mechanically.
@@ -34,6 +34,14 @@ public SyntaxEditor(SyntaxNode root, Workspace workspace) | |||
/// Creates a new <see cref="SyntaxEditor"/> instance. | |||
/// </summary> | |||
public SyntaxEditor(SyntaxNode root, HostWorkspaceServices services) |
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.
yes. will do.
namespace Microsoft.CodeAnalysis.Host | ||
{ | ||
// TODO(cyrusn): Make public. Tracked through https://github.com/dotnet/roslyn/issues/62914 | ||
internal sealed class HostProjectServices |
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'm very very hesitant on structs as it is a breaking change to make them classes and it's hard to tell up front if being a struct will be an issue for us (for example, having to deal with potentially default values).
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.
default value is the same as null in this case, in public APIs we would need to check either way
|
||
// This ensures a single instance of this type associated with each HostLanguageServices. | ||
[Obsolete("Do not call directly. Use HostLanguageServices.ProjectServices to acquire an instance")] | ||
internal HostProjectServices(HostLanguageServices services) |
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.
Obsolete wouldn't be needed if this was a struct.
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.
yes. but then i have to override ==
and validate all cases whre code checks identity are correct.
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 think you need to override ==
. Struct does not have to have value equality.
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.
currently we have code that checks if the Services instances are the same instance. I wanted to avoid having to go find and audit all of those (esp. as we have no facilty for searching for use of reference equality == on these types
. :)
namespace Microsoft.CodeAnalysis.Host | ||
{ | ||
// TODO(cyrusn): Make public. Tracked through https://github.com/dotnet/roslyn/issues/62914 | ||
internal sealed class HostSolutionServices |
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.
Seems like in most (all?) cases the caller of SyntaxEditor ctor has a document on hand. Would it make sense to use the extension method in all these call sites? |
I don't have a problem with that, but it's currently not necessary. I'm trying to make minimal changes to get us off of Solution.Workspace (and hte other associated banned pathways). Extraneous work/cleanup just adds time to that :) |
Yeah, but this leaves us in rather inconsistent state where we have multiple ways of using some APIs. I'd prefer not to increase the amount of inconsistency. |
The intent is to remove that extension once hte API review happens as it won't be needed anymore. |
We intend to add
solutionInstance.Workspace
to the banned api list for roslyn itself. It's highly problematic for OOP, as we have to try to replicate that concept, which isn't something sensical in that world. First, OOP cannot mutation things, so exposing the mutable workspace doesn't make much sense. Second, in VS you can have many workspaces, but in OOP we map that all back to one, which means we don't have a proper representation of VS state (for example, where you might have the VSWorkspace and the Metadata-as-source workspace). This means those features either cannot use OOP, or they try to use OOP and can end up with non-sensical results.This is a series of PRs to get us off of that API so we can move to a much cleaner and simpler OOP model for the solution and services.