所以我正在尝试为DSL创建自己的visual studio语言插件。我的问题是,我已经实现了LanguageService
并覆盖了GetScanner。通过调试,我发现它实际上返回了IScanner
实现,但它从不调用ScanTokenAndProvideInfoAboutIt
。
所有这些加载都是在打开带有我的语言包所附带扩展名的文件后发生的,这让我相信它实际上是在尝试使用我的插件。
我在这里有点迷失,创建视觉工作室插件的过程在表面看起来很直观,但似乎被掩盖了。
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
}