Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Visual Studio decide when and how to rebuild IntelliSense?

I'm trying to write a code generation tool. For this tool it's important that the generated code is available prior to building (i.e., for IntelliSense). I know Visual Studio will at least partially evaluate the project build plan automatically to generate IntelliSense, but I can't find much information on the details.

As a simpler example, let's say I want to take all items with build action None and compile them. I have a project like this:

<Project [...]>
  [...]
  <Compile Include="Foo.cs" />
  <None Include="Bar.cs" />
</Project>

One way to get Bar.cs to compile is to add the following to the project:

<PropertyGroup>
  <CoreCompileDependsOn>
    $(CoreCompileDependsOn);IndirectCompile
  </CoreCompileDependsOn>
</PropertyGroup>
<Target Name="IndirectCompile">
  <CreateItem Include="@(None)">
    <Output ItemName="Compile" TaskParameter="Include" />
  </CreateItem>
</Target>

If I do it this way, Visual Studio acts basically the same as if Bar.cs had the Compile action to begin with. IntelliSense is fully available; if I make a change in Bar.cs it's reflected immediately (well, as immediate as the background operation normally is) in IntelliSense when I'm editing Foo.cs, and so on.

However, say instead of directly compiling the None entry, I want to copy it to the obj directory and then compile it from there. I can do this by changing the IndirectCompile target to this:

<Target Name="IndirectCompile" 
        Inputs="@(None)"
        Outputs="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')"
>
  <Copy SourceFiles="@(None)"
        DestinationFiles="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')"
  >
    <Output TaskParameter="DestinationFiles" ItemName="Compile" />
  </Copy>
</Target>

Doing this causes IntelliSense to stop updating. The task works on build, dependency analysis and incremental building work, Visual Studio just stops automatically running it when an input file is saved.

So, that leads to the title question: How does Visual Studio choose to run targets or not for IntelliSense? The only official documentation I've found has been this, specifically the "Design-Time IntelliSense" section. I'm pretty sure my code meets all those criteria. What am I missing?

like image 212
Jacob Avatar asked Apr 28 '13 19:04

Jacob


People also ask

How do I rebuild IntelliSense in Visual Studio?

In Visual Studio 2022, open Tools -> Options -> [type in "database" in the search box] -> Text Editor -> C/C++ -> Advanced -> Recreate Database = TRUE, and then reopen the solution. Save this answer.

How does IntelliSense work in Visual Studio?

IntelliSense is a code-completion aid that includes a number of features: List Members, Parameter Info, Quick Info, and Complete Word. These features help you to learn more about the code you're using, keep track of the parameters you're typing, and add calls to properties and methods with only a few keystrokes.

Why is IntelliSense not working Visual Studio 2022?

Please try: Go to Visual Studio Installer, click Modify , uncheck IntelliCode in Individual components, then click Modify button to save the change, wait for the installation to complete, and then reinstall IntelliCode . In Visual Studio, go to Tools->Options->IntelliCode to check if the setting is Default.


1 Answers

After a few days of experimenting and poking around in the debugger I think I have found the answer, and unfortunately that answer is that this is not possible (at least not in a clearly supported way -- I'm sure there are ways to trick the system).

When a project is loaded, and when the project itself changes (files added/removed, build actions changed, etc), the IntelliSense build is executed (csproj.dll!CLangCompiler::RunIntellisenseBuild). This build will run tasks up to and including the Csc task. Csc will not execute normally, but instead just feed its inputs back into its host (Visual Studio).

From this point on, Visual Studio keeps track of the files that were given as Sources to the Csc task. It will monitor those files for changes, and when they change, update IntelliSense. So in my example, if I manually edit Bar.g.cs those changes will be picked up. But the build tasks themselves will not be run again until the project changes or a build is explicitly requested.

So, that's disappointing, but not surprising, I guess. It also explains something else I had always wondered about -- XAML files with a code-behind tend to have a Custom Tool action of MSBuild:Compile, presumably for exactly this reason.

I'm going to mark this as the answer, but I'd love to be told I'm wrong and that I missed something.

like image 84
Jacob Avatar answered Nov 15 '22 19:11

Jacob