Question

I just migrated my language service from VS2008 to VS2010. Everything works fine except for one important thing: I no longer get LanguageService.ParseSource invoked for ParseReason.Check. It do get a single invoke after opening a file. But after editing code, it no longer gets invoked.

Any ideas what could be causing that?

No correct solution

OTHER TIPS

I also migrated a language service from 2008 to 2010. Can you check if you've fallowed all of these steps?

http://msdn.microsoft.com/en-us/library/dd885475.aspx

I didn't have to do anything else, which I verified by diffing the important files in our depot before and after the change.

I don't know if you ever figured your question out, but have you tried making sure that your Source class' LastParseTime is set to 0 when creating it? I seem to recall some issues with Check not happening unless you manually set LastParseTime to 0 when creating your Source object.

Protip: If you use .NET Reflector, you can disassemble all of the base classes for the LanguageService framework and get a pretty good understanding of how it all works under the hood. The classes you'd be interested in live in Microsoft.VisualStudio.Package.LanguageService.10.0.dll, which should be installed in the GAC. I've found this to be unimaginably helpful when trying to figure out why things weren't working in my own Language Service, and being able to step through the source code in the debugger mitigates almost all the pain of working with these frameworks!

When your Source object is initialized, it starts off with a LastParseTime of Int32.MaxValue. The code that causes fires off a ParseRequest with ParseReason.Check checks the LastParseTime value to see if the time since the last change to the text is less than the time it takes to run a parse (or the CodeSenseDelay setting, whichever is greater).

The code that handles the response from ParseSource is supposed to set the LastParseTime, but as far as I can tell, it only does that if the ParseReason is Check.

You can get around this issue by setting Source.LastParseTime = 0 when you initialize your Source. This has the side-effect of setting CompletedFirstParse to true, even if the first parse hasn't finished yet.

Another way to fix this issue is to override Source.OnIdle to fire off the first call to BeginParse() This is the way I would recommend.

public override void OnIdle(bool periodic)
{
    // Once first "Check" parse completes, revert to base implementation
    if (this.CompletedFirstParse)
    {
        base.OnIdle(periodic);
    }
    // Same as base implementation, except we don't check lastParseTime
    else if (!periodic || this.LanguageService == null || this.LanguageService.LastActiveTextView == null || (this.IsCompletorActive) || (!this.IsDirty || this.LanguageService.IsParsing))
    {
        this.BeginParse();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top