所以我正在尝试为 DSL 创建我自己的视觉工作室语言插件。我的问题是,我已经实现LanguageService
并覆盖了 GetScanner。通过调试,我看到它实际上返回了IScanner
实现,但它从不调用ScanTokenAndProvideInfoAboutIt
.
所有这些加载都是在打开一个扩展名为我的语言包的文件之后发生的,这让我相信它实际上是在尝试使用我的插件。
我在这里有点迷茫,创建 Visual Studio 插件的过程表面上看起来很直观,但在幕后似乎受到了诅咒。
internal class ValLanguageScanner : IScanner
{
private IVsTextBuffer m_buffer;
string m_source;
public ValLanguageScanner(IVsTextBuffer buffer)
{
// Breakpoint gets hit here(to to creation in GetScanner method)
m_buffer = buffer;
}
bool IScanner.ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state)
{
// Breakpoint never gets hit here
var foundToken = false;
return foundToken;
}
void IScanner.SetSource(string source, int offset)
{
m_source = source.Substring(offset);
}
}
public class ValLanguageService : LanguageService
{
private const string _name = "Val";
private LanguagePreferences m_preferences;
private ValLanguageScanner m_scanner;
public override LanguagePreferences GetLanguagePreferences()
{
if (m_preferences == null)
{
m_preferences = new LanguagePreferences(this.Site,typeof(ValLanguageService).GUID,this.Name);
m_preferences.Init();
}
return m_preferences;
}
public override IScanner GetScanner(IVsTextLines buffer)
{
if (m_scanner == null)
{
m_scanner = new ValLanguageScanner(buffer);
}
return m_scanner;
}
public override AuthoringScope ParseSource(ParseRequest req)
{
return new ValLanguageAuthoringScope();
}
public override string GetFormatFilterList()
{
return "Val(*.val)|*.val";
}
public override string Name
{
get { return _name; }
}
}
[PackageRegistration(UseManagedResourcesOnly = true)]
[ProvideServiceAttribute(typeof(ValLanguageService),
ServiceName = "Val Language Service")]
[ProvideLanguageExtensionAttribute(typeof(ValLanguageService),
".val")]
[ProvideLanguageExtensionAttribute(typeof(ValLanguageService),
".vallist")]
[InstalledProductRegistration("#110", "#112", "1.0")]
public class ValLanguagePackage : Package, IOleComponent
{
private uint m_componentID;
public ValLanguagePackage()
{
Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
}
protected override void Initialize()
{
base.Initialize(); // required
// Proffer the service.
IServiceContainer serviceContainer = this as IServiceContainer;
ValLanguageService langService = new ValLanguageService();
langService.SetSite(this);
serviceContainer.AddService(typeof(ValLanguageService),
langService,
true);
// Register a timer to call our language service during
// idle periods.
IOleComponentManager mgr = GetService(typeof(SOleComponentManager))
as IOleComponentManager;
if (m_componentID == 0 && mgr != null)
{
OLECRINFO[] crinfo = new OLECRINFO[1];
crinfo[0].cbSize = (uint)Marshal.SizeOf(typeof(OLECRINFO));
crinfo[0].grfcrf = (uint)_OLECRF.olecrfNeedIdleTime |
(uint)_OLECRF.olecrfNeedPeriodicIdleTime;
crinfo[0].grfcadvf = (uint)_OLECADVF.olecadvfModal |
(uint)_OLECADVF.olecadvfRedrawOff |
(uint)_OLECADVF.olecadvfWarningsOff;
crinfo[0].uIdleTimeInterval = 1000;
int hr = mgr.FRegisterComponent(this, crinfo, out m_componentID);
}
}
protected override void Dispose(bool disposing)
{
if (m_componentID != 0)
{
Debug.WriteLine("OMG DISPOSING");
IOleComponentManager mgr = GetService(typeof(SOleComponentManager))
as IOleComponentManager;
if (mgr != null)
{
int hr = mgr.FRevokeComponent(m_componentID);
}
m_componentID = 0;
}
Debug.WriteLine("OMG DISPOSING BASE");
base.Dispose(disposing);
Debug.WriteLine("OMG DISPOSED");
}
#region IOleComponent Members
public int FDoIdle(uint grfidlef)
{
bool bPeriodic = (grfidlef & (uint)_OLEIDLEF.oleidlefPeriodic) != 0;
// Use typeof(TestLanguageService) because we need to
// reference the GUID for our language service.
LanguageService service = GetService(typeof(ValLanguageService))
as LanguageService;
if (service != null)
{
service.OnIdle(bPeriodic);
}
return 0;
}
public int FContinueMessageLoop(uint uReason,
IntPtr pvLoopData,
MSG[] pMsgPeeked)
{
return 1;
}
public int FPreTranslateMessage(MSG[] pMsg)
{
return 0;
}
public int FQueryTerminate(int fPromptUser)
{
return 1;
}
public int FReserved1(uint dwReserved,
uint message,
IntPtr wParam,
IntPtr lParam)
{
return 1;
}
public IntPtr HwndGetWindow(uint dwWhich, uint dwReserved)
{
return IntPtr.Zero;
}
public void OnActivationChange(IOleComponent pic,
int fSameComponent,
OLECRINFO[] pcrinfo,
int fHostIsActivating,
OLECHOSTINFO[] pchostinfo,
uint dwReserved)
{
}
public void OnAppActivate(int fActive, uint dwOtherThreadID)
{
}
public void OnEnterState(uint uStateID, int fEnter)
{
}
public void OnLoseActivation()
{
}
public void Terminate()
{
}
#endregion
}