dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.17k stars 1.34k forks source link

Language Service for MSBuild #1774

Open rainersigwald opened 7 years ago

rainersigwald commented 7 years ago

Currently, MSBuild gets syntax highlighting in most cases by piggybacking on XML. In Visual Studio, there is also some code completion based on XSDs.

This is better than nothing but doesn't help with the particularly hard parts of MSBuild, like completion of property names or item transforms.

It would be nice if there was a broadly-compatible language service that worked in (at least) VS, VS Code, and VS Mac.

rainersigwald commented 7 years ago

We have been talking about this for years but I couldn't find an issue to track it.

Prior art: @mhutch's https://github.com/mhutch/MonoDevelop.MSBuildEditor.

rainersigwald commented 7 years ago

Strong desire: an indication of the common but hard-to-diagnose error "you're using $() to reference an item/@() to reference a property" when only one or the other but not both is defined.

Similarly, having visual disambiguation between an item name and a property name could be extremely helpful.

KirillOsenkov commented 7 years ago

Not sure if it can be useful, but I have a full-fidelity XML parser with no dependencies: https://github.com/KirillOsenkov/XmlParser

Also the old internal MSBuild source code has a prototype-level MSBuild language service written using ANTLR: \src\xmake\LanguageService

Finally, it might be worth following up with XAML folks to see what we can reuse there. XAML language service is pretty powerful.

/cc @piotrpMSFT @mlorbetske

rainersigwald commented 7 years ago

In my head, we'd plug into a project using our current evaluation model. I think it exposes almost all of the information you'd need for both colorization and completion. I hope we wouldn't need to write a grammar from scratch that's a superset of XML. I'm a bit shocked that someone tried!

danmoseley commented 7 years ago

"you're using $() to reference an item/@() to reference a property" when only one or the other but not both is defined.

Stuff like that could be in a /lint mode. Not necessarily possible for a langauge service to see statically.

rainersigwald commented 7 years ago

/lint mode

Yeah, good somewhat orthogonal thought. Filed #1777.

I think a reasonable language service could have enough information to do this, at least for outside-of-targets definitions . . . if it was evaluating the project in the right environment, which is a big consideration for the language service. Should be easy enough to get "the right environment" when in VS, but potentially harder in other environments.

tintoy commented 6 years ago

Hi - just saw this issue while searching for something else, and figured I'd leave this here for anyone who else who comes across it:

https://github.com/tintoy/msbuild-project-tools-vscode/

It's LSP-compatible (currently works with VS Code and Eclipse) so feel free to reuse if it helps.

tintoy commented 6 years ago

(it also has support for parsing and interpreting MSBuild expressions)

KirillOsenkov commented 6 years ago

I think at this point @mhutch's language service is the clear winner in terms of functionality: https://twitter.com/mjhutchinson/status/941214242644086784

tintoy commented 6 years ago

Functionality looks the same to me but if that's what best fits your use-case then fair enough :)

danmoseley commented 5 years ago

A language service needs a way to discover what items and properties to suggest. That shouldn't be the XSD. The XSD always was a big hack from day one. It is hard to read/grok, big and fat, non contextual, and relies on a single point of truth. In contrast the AvailableItemName concept has been successful because it allowed props/targets to add entries by convention in a simple decentralized way.

We could replace the XSDs with a similar convention rooted in the props files. For example <AvailableItemNameFile Include="myitems.items"/> where myitems.items is MSBuild format using conventions to describe properties, items and metadata. The file is not <Import>ed so it does not add bloat to project load/build. But it linked from the props file so that it is contextual to the project being edited.

KirillOsenkov commented 5 years ago

@danmosemsft make sure you saw https://github.com/mhutch/MonoDevelop.MSBuildEditor. It has videos what it can do. It doesn't use XSD but uses custom logic to intelligently calculate available completion items.

We're going to port it to VS editor soon.

Pilchie commented 5 years ago

Tagging @panopticoncentral who has been looking at this space lately too.

danmoseley commented 5 years ago

Hey, that looks great. I see it uses a json sidecar file - I guess that works too.

KirillOsenkov commented 5 years ago

@mhutch

mhutch commented 5 years ago

I'd love to hear comments on my MSBuild schema format. Hoping to finalize it soon so folks can start shipping sidecar schemas alongside their targets..