Skip to content
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

Bugfixes for the OmniSharp ExternalAcces layer #53253

Merged
merged 2 commits into from
May 11, 2021

Conversation

333fred
Copy link
Member

@333fred 333fred commented May 7, 2021

  1. Make the completion provider class names constants so they can be used in pattern matching. I've added a unit test to make sure that these names are correct.
  2. Correctly handle default options arrays in OmniSharpPickMembersService.

1. Make the completion provider class names constants so they can be used in pattern matching. I've added a unit test to make sure that these names are correct.
2. Correctly handle default options arrays in OmniSharpPickMembersService.
@333fred 333fred requested review from a team as code owners May 7, 2021 06:03
@333fred 333fred requested a review from sharwell May 7, 2021 06:03
@333fred
Copy link
Member Author

333fred commented May 7, 2021

@sharwell for a quick review.

@jinujoseph, is this ok to take for 16.11?

Comment on lines 9 to 14
internal const string ObjectCreationCompletionProvider = "Microsoft.CodeAnalysis.CSharp.Completion.Providers.ObjectCreationCompletionProvider";
internal const string OverrideCompletionProvider = "Microsoft.CodeAnalysis.CSharp.Completion.Providers.OverrideCompletionProvider";
internal const string PartialMethodCompletionProvider = "Microsoft.CodeAnalysis.CSharp.Completion.Providers.PartialMethodCompletionProvider";
internal const string InternalsVisibleToCompletionProvider = "Microsoft.CodeAnalysis.CSharp.Completion.Providers.InternalsVisibleToCompletionProvider";
internal const string TypeImportCompletionProvider = "Microsoft.CodeAnalysis.CSharp.Completion.Providers.TypeImportCompletionProvider";
internal const string ExtensionMethodImportCompletionProvider = "Microsoft.CodeAnalysis.CSharp.Completion.Providers.ExtensionMethodImportCompletionProvider";
Copy link
Member

@sharwell sharwell May 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should all be static readonly to ensure they are not embedded as literals into external code.

... so they can be used in pattern matching ...

This will unfortunately not be possible without compromising the ability of the external access layer to adapt to changes.

Copy link
Member Author

@333fred 333fred May 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to keep these as constants. I don't think we have a real problem here: OmniSharp controls what version of Roslyn they take, no one is going to be upgrading it to a new version at runtime. We have tests now to ensure that these reflect the real names of the types, and the code in O# that uses these names has made pretty significant usage of pattern matching.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The external access layer ships with Roslyn itself. The value of these strings is allowed to change as long as the following two requirements hold:

  1. The name of the field stays the same
  2. The value of the field is the new type name for the completion provider with the same concept

Embedding the strings in a binary outside of Roslyn breaks the ability to change the value in account for (2).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other words, Roslyn is allowed to change the constant value here and create an assembly binding redirection that forces the new value to appear at runtime. Any code referencing these as const would no longer behave correctly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other words, Roslyn is allowed to change the constant value here and create an assembly binding redirection that forces the new value to appear at runtime.

There is no one to create such a binding redirect. OmniSharp is the host process here, and controls the final version of Roslyn being used. It's never going to be using a different version of the external access library than the rest of roslyn. While I get the theoretical concern here, I don't believe it matters for this external access library and I'm going to keep these as constants. Again, there is significant code in OmniSharp that already uses these as constants, and I'm not going to rewrite this code to a wildly different form to conform to theoretical concerns. I'll just not use these fields and leave them as the OmniSharp-copied constants.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can i ask a clarifying question: what value do we get from constants here? they seem strictly more brittle than static readonlies.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can i ask a clarifying question: what value do we get from constants here? they seem strictly more brittle than static readonlies.

Constants can appear in the arms of a switch expression, but static readonly cannot.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or any pattern matches: as mentioned, the completion code in OmniSharp makes quite a bit of use of pattern matching over these names today.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I'll revert this. But ultimately, I'm not going to be changing the code in omnisharp here. It just means we're going to have constants there and not use these fields.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@333fred maybe a situation to keep on the back of your mind it case future pattern matching improvements come through LDM 😄

@jinujoseph
Copy link
Contributor

yes Fred , will approve post review

@333fred 333fred requested a review from sharwell May 10, 2021 23:27
@333fred
Copy link
Member Author

333fred commented May 11, 2021

@jinujoseph for approval.

@333fred 333fred merged commit 1d7d0c2 into dotnet:release/dev16.11 May 11, 2021
@333fred 333fred deleted the osharp-externalaccess-fixup branch May 11, 2021 23:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants