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

Make completion service public #8170

Merged
merged 2 commits into from
May 4, 2016
Merged

Make completion service public #8170

merged 2 commits into from
May 4, 2016

Conversation

mattwar
Copy link
Contributor

@mattwar mattwar commented Jan 26, 2016

This change makes the completion API public.

Lots of refactoring.

if (_importedProviders == null)
{
var language = this.GetLanguageName();
var mefExporter = (IMefHostExportProvider)_workspace.Services.HostServices;
Copy link
Member

Choose a reason for hiding this comment

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

What if this type doesn't implement that interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It always does now. We have this dependency in a few places already.

@Pilchie
Copy link
Member

Pilchie commented Jan 26, 2016

Pretty sure @DustinCampbell and @rchande will want to look at this too.

@@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols
/// <summary>
/// Represents an assembly built by compiler.
/// </summary>
internal sealed class SourceAssemblySymbol : MetadataOrSourceAssemblySymbol, IAttributeTargetSymbol
internal sealed class SourceAssemblySymbol : MetadataOrSourceAssemblySymbol, ISourceAssemblySymbol, IAttributeTargetSymbol
Copy link
Member

Choose a reason for hiding this comment

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

Is this supposed to be part of your change?

@mattwar
Copy link
Contributor Author

mattwar commented Mar 24, 2016

@dotnet-bot test eta

@mattwar mattwar changed the title Remove providers from ICompletionService Make completion service public Mar 24, 2016
@mattwar
Copy link
Contributor Author

mattwar commented Mar 25, 2016

Okay @DustinCampbell @Pilchie @rchande @CyrusNajmabadi

Here's the real proposed change with all the bits made public.

@@ -0,0 +1,68 @@
diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Commit.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller_Commit.cs
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have not idea. I did not create it.

@rchande
Copy link
Contributor

rchande commented Apr 1, 2016

@mattwar: I looked through this and nothing seemed obviously wrong to me. I did want to build it locally and try things out. However you're missing some changes in master (as you can see from Jenkins) and I encountered a ton of merge commits trying to sync.

@mattwar
Copy link
Contributor Author

mattwar commented May 4, 2016

retest prtest/win/vsi/p0 please
retest prtest/win/vsi/p2 please

@mattwar mattwar merged commit 1a3b616 into dotnet:master May 4, 2016
@npolyak
Copy link

npolyak commented May 17, 2016

When will the changes for this Issue make it into a NuGet release (which release is going to be associated with these changes?)

@Pilchie
Copy link
Member

Pilchie commented May 17, 2016

You can get them on our 1.3 myget feed already, and they should show up on NuGet when our 1.3 release comes out (with VS 2015 Update 3).

@DustinCampbell
Copy link
Member

Yup! Here's the myget feed: http://myget.org/gallery/roslyn-master-nightly

@npolyak
Copy link

npolyak commented May 18, 2016

Thanks

@npolyak
Copy link

npolyak commented May 19, 2016

How do I get a reference to the completion service?

I am getting the language services from a C# project or from a workspace containing it:
HostLanguageServices csServices = MyWorkspace.Services.GetLanguageServices("C#");

but then csServices.GetService() returns null.

THanks
Nick

@Pilchie
Copy link
Member

Pilchie commented May 19, 2016

What sort of Workpace are you in? Is it possible that the CSharpFeatures assembly is not part of the MEF composition used to populate the workspace and language services?

@npolyak
Copy link

npolyak commented May 19, 2016

After I created my own MefHostServices with the composition container that loaded CSharpFeatures and created the Workspace based on that, I started getting the completion service, but should not there be a better way to do it?

Here is my code:

       var assemblies = new[]
        {
            Assembly.Load("Microsoft.CodeAnalysis"),
            Assembly.Load("Microsoft.CodeAnalysis.CSharp"),
            Assembly.Load("Microsoft.CodeAnalysis.Features"),
            Assembly.Load("Microsoft.CodeAnalysis.CSharp.Features")
        };
        _compositionContext = new ContainerConfiguration()
            .WithAssemblies(MefHostServices.DefaultAssemblies.Concat(assemblies))
            .CreateContainer();
        _host = MefHostServices.Create(_compositionContext);
        TheWorkspace = new AdhocWorkspace(_host, "Host");

Is there a better way to make sure the CompletionServices exist?

@Pilchie
Copy link
Member

Pilchie commented May 19, 2016

I don't know of a better way to do it. @mattwar Should we consider adding adding these two MefHostServices.DefaultAssemblies, or providing other built-ins?

@mattwar
Copy link
Contributor Author

mattwar commented May 19, 2016

@Pilchie that sort of makes sense, seeing as we are making these APIs public now.

@npolyak
Copy link

npolyak commented May 23, 2016

How can I get the type of a CompletionItem now (whether it is a property or a method or an event)?

Before you had a Glyph property on the CompletionItem - but it is no longer there.

Thanks

@npolyak
Copy link

npolyak commented May 23, 2016

I think i got it - it is now in Tags. Still I think an enumeration would be better.

@npolyak
Copy link

npolyak commented May 23, 2016

Let me clarify myself - from my point of view - it would be better to rename the Glyph enumeration to CompletionType, make it public and create a public CompletionType property within CompletionItem class. That way the ViewModel does not have any hints of View constracts (like Glyph) and value conversion can achieve transformation between the CompletionType and the corresponding image.

@CyrusNajmabadi
Copy link
Member

Can you explain why CompletionTag is insufficient? Thanks!

https://github.com/dotnet/roslyn/blob/master/src/Features/Core/Portable/Completion/CompletionTags.cs

@npolyak
Copy link

npolyak commented May 24, 2016

Hey Cyrus,
it is simply much clearer and more type safe, which is better for learning the code and using it.
The tags are strings that potentially can contain anything. CompletionType can be a predefined enumeration that can only contain certain values.
Imagine a person learning the code - and I was such person very recently - He can go to the definition of the CompletionType and learn what it is without running the application. I had to run the application and in the beginning I simply did not realize that the Tags array had to be opened to get the type of the completions. Also even now, I do not know, perhaps sometimes it can contain smth completely different. Finally your own developers might not understand what it is for and use it for something else, resulting in an error.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented May 24, 2016

The tags are strings that potentially can contain anything.

Yes, that's a virtue :)

CompletionType can be a predefined enumeration that can only contain certain values.

That's a problem. Now we need to know the set of things that will go in completion. As this is an extensible API that we would like any language to be able to plug into, that's not ok.

Also even now, I do not know, perhaps sometimes it can contain smth completely different.

Yes. It may. Any code processing it will have to handle this case.

Finally your own developers might not understand what it is for and use it for something else, resulting in an error.

It can be used for anything else. The point is that's its a mechanism to allow people to use it how they want.

We're moving away from being prescriptive here. That's because it's really hard to be both prescriptive, while still being generally usable by any language. Instead, we allow providers to be descriptive. They loosely state what they are, and consumers can loosely process what they understand.

@npolyak
Copy link

npolyak commented May 25, 2016

I do not want to spend much time arguing, but the strong typing is very important for the ease of usage and in no way restrictive (when you have a new completion type you can always modify the enumeration).

@DustinCampbell
Copy link
Member

@npolyak, modifying an enumeration is actually an API breaking change. It can break existing code that uses the enumeration.

@npolyak
Copy link

npolyak commented May 25, 2016

Using the same logic, one can drop all the strong types because modifying them is an API breaking change.

@DustinCampbell
Copy link
Member

No, that's not true at all. Adding members to enumerations can specifically break existing code, for example a switch case that tests every value and throws in the default case. That'll fail at runtime.

That does not extend to, say, classes, where members can be added in a non-breaking way.

@npolyak
Copy link

npolyak commented May 25, 2016

Yes, if e.g you remove a class field and there is a code which uses that field, it can definitely break. The key is - the word 'can' - both enum and class change can break existing API but do not have to.

A shift towards less type safe approach brings more problems from my point of view than benefits. Anyways I rest my case.

@DustinCampbell
Copy link
Member

Appreciate the feedback.

@aelij
Copy link
Contributor

aelij commented Jun 1, 2016

I was also somewhat irked to find Glyph missing from the public API, but this makes total sense. Thanks for the explanation.

Wouldn't it be better for Tags to be a dictionary, though? It would make the ImageMonikers class (and similar implementations) much nicer. For example, you could have Tags.TryGetValue(TagCategories.Accessibility, out accessibility)

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.

8 participants