| @@ -0,0 +1,137 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using Microsoft.VisualStudio; | |||||
| using Microsoft.VisualStudio.Package; | |||||
| using Microsoft.VisualStudio.TextManager.Interop; | |||||
| using Microsoft.VisualStudio.OLE.Interop; | |||||
| namespace Lol.VisualStudio.Plugin | |||||
| { | |||||
| class LolFxLanguageService : LanguageService | |||||
| { | |||||
| public override string GetFormatFilterList() | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| public override LanguagePreferences GetLanguagePreferences() | |||||
| { | |||||
| if (m_preferences == null) | |||||
| { | |||||
| m_preferences = new LanguagePreferences(this.Site, | |||||
| typeof(LolFxLanguageService).GUID, this.Name); | |||||
| m_preferences.Init(); | |||||
| } | |||||
| return m_preferences; | |||||
| } | |||||
| public override IScanner GetScanner(IVsTextLines buffer) | |||||
| { | |||||
| if (m_scanner == null) | |||||
| { | |||||
| m_scanner = new LolFxScanner(buffer); | |||||
| } | |||||
| return m_scanner; | |||||
| } | |||||
| public override string Name | |||||
| { | |||||
| get { return "LolFx"; } | |||||
| } | |||||
| public override AuthoringScope ParseSource(ParseRequest req) | |||||
| { | |||||
| return new LolFxAuthoringScope(); | |||||
| } | |||||
| private LanguagePreferences m_preferences; | |||||
| private LolFxScanner m_scanner; | |||||
| internal class LolFxScanner : IScanner | |||||
| { | |||||
| public LolFxScanner(IVsTextBuffer buffer) | |||||
| { | |||||
| m_buffer = buffer; | |||||
| } | |||||
| bool IScanner.ScanTokenAndProvideInfoAboutIt(TokenInfo tokeninfo, ref int state) | |||||
| { | |||||
| while (m_offset < m_source.Length) | |||||
| { | |||||
| if (m_source[m_offset] == ' ' || m_source[m_offset] == '\t') | |||||
| { | |||||
| ++m_offset; | |||||
| continue; | |||||
| } | |||||
| tokeninfo.StartIndex = m_offset; | |||||
| tokeninfo.EndIndex = m_offset; | |||||
| tokeninfo.Type = TokenType.Unknown; | |||||
| switch (state % 4) | |||||
| { | |||||
| case 0: tokeninfo.Color = TokenColor.Number; break; | |||||
| case 1: tokeninfo.Color = TokenColor.Text; break; | |||||
| case 2: tokeninfo.Color = TokenColor.Keyword; break; | |||||
| case 3: tokeninfo.Color = TokenColor.Comment; break; | |||||
| } | |||||
| ++m_offset; | |||||
| ++state; | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| enum State | |||||
| { | |||||
| Default, | |||||
| CComment, | |||||
| CppComment, | |||||
| String, | |||||
| } | |||||
| void IScanner.SetSource(string source, int offset) | |||||
| { | |||||
| m_source = source; | |||||
| m_offset = offset; | |||||
| } | |||||
| private IVsTextBuffer m_buffer; | |||||
| string m_source; | |||||
| int m_offset; | |||||
| } | |||||
| internal class LolFxAuthoringScope : AuthoringScope | |||||
| { | |||||
| public override string GetDataTipText(int line, int col, out TextSpan span) | |||||
| { | |||||
| span = new TextSpan(); | |||||
| return null; | |||||
| } | |||||
| public override Declarations GetDeclarations(IVsTextView view, | |||||
| int line, | |||||
| int col, | |||||
| TokenInfo info, | |||||
| ParseReason reason) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| public override string Goto(VSConstants.VSStd97CmdID cmd, IVsTextView textView, int line, int col, out TextSpan span) | |||||
| { | |||||
| span = new TextSpan(); | |||||
| return null; | |||||
| } | |||||
| public override Methods GetMethods(int line, int col, string name) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -91,14 +91,14 @@ namespace Lol.VisualStudio.Plugin | |||||
| if (cmd == null) | if (cmd == null) | ||||
| return; | return; | ||||
| cmd.ClearOutputPane(); | |||||
| cmd.WriteToOutputPane("------ Build started: Generating Compilers ------\n"); | |||||
| Logger.Clear(); | |||||
| Logger.Info("------ Build started: Generating Compilers ------\n"); | |||||
| int scanner_count = 0, parser_count = 0, error_count = 0; | int scanner_count = 0, parser_count = 0, error_count = 0; | ||||
| foreach (Project project in cmd.projects) | foreach (Project project in cmd.projects) | ||||
| { | { | ||||
| cmd.WriteToOutputPane("Project " + project.Name + "\n"); | |||||
| Logger.Info("Project " + project.Name + "\n"); | |||||
| string project_path = Path.GetDirectoryName(project.FullName); | string project_path = Path.GetDirectoryName(project.FullName); | ||||
| @@ -137,7 +137,7 @@ namespace Lol.VisualStudio.Plugin | |||||
| if (item.Name.EndsWith("-scanner.l")) | if (item.Name.EndsWith("-scanner.l")) | ||||
| { | { | ||||
| cmd.WriteToOutputPane("flex.exe " + filename + "\n"); | |||||
| Logger.Info("flex.exe " + filename + "\n"); | |||||
| string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-scanner.l"))); | string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-scanner.l"))); | ||||
| if (!cmd.Run(project_path, | if (!cmd.Run(project_path, | ||||
| @@ -153,7 +153,7 @@ namespace Lol.VisualStudio.Plugin | |||||
| if (item.Name.EndsWith("-parser.y")) | if (item.Name.EndsWith("-parser.y")) | ||||
| { | { | ||||
| cmd.WriteToOutputPane("bison.exe " + filename + "\n"); | |||||
| Logger.Info("bison.exe " + filename + "\n"); | |||||
| string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-parser.y"))); | string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-parser.y"))); | ||||
| if (!cmd.Run(project_path, | if (!cmd.Run(project_path, | ||||
| @@ -173,7 +173,7 @@ namespace Lol.VisualStudio.Plugin | |||||
| } | } | ||||
| } | } | ||||
| cmd.WriteToOutputPane(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n", | |||||
| Logger.Info(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n", | |||||
| scanner_count, parser_count, error_count)); | scanner_count, parser_count, error_count)); | ||||
| } | } | ||||
| @@ -202,52 +202,26 @@ namespace Lol.VisualStudio.Plugin | |||||
| string output = p.StandardError.ReadToEnd() | string output = p.StandardError.ReadToEnd() | ||||
| + p.StandardOutput.ReadToEnd(); | + p.StandardOutput.ReadToEnd(); | ||||
| p.WaitForExit(); | p.WaitForExit(); | ||||
| WriteToOutputPane(output); | |||||
| Logger.Info(output); | |||||
| if (p.ExitCode != 0) | if (p.ExitCode != 0) | ||||
| { | { | ||||
| WriteToOutputPane("Error: " + executable + " exited with code " + p.ExitCode + "\n"); | |||||
| Logger.Info("Error: " + executable + " exited with code " + p.ExitCode + "\n"); | |||||
| if (arguments != "") | if (arguments != "") | ||||
| WriteToOutputPane("Error: args: " + arguments + "\n"); | |||||
| Logger.Info("Error: args: " + arguments + "\n"); | |||||
| if (env != "") | if (env != "") | ||||
| WriteToOutputPane("Error: env: " + env + "\n"); | |||||
| Logger.Info("Error: env: " + env + "\n"); | |||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| catch (Exception e) | catch (Exception e) | ||||
| { | { | ||||
| WriteToOutputPane("Error: failed to launch " + executable + "\n"); | |||||
| Logger.Info("Error: failed to launch " + executable + "\n"); | |||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| private void ClearOutputPane() | |||||
| { | |||||
| IVsOutputWindow win = sp.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow; | |||||
| if (null == win) | |||||
| { | |||||
| Trace.WriteLine("Failed to get a reference to IVsOutputWindow"); | |||||
| pane = null; | |||||
| } | |||||
| Guid guid = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; | |||||
| if (Microsoft.VisualStudio.ErrorHandler.Failed(win.GetPane(ref guid, out pane))) | |||||
| { | |||||
| Trace.WriteLine("Failed to get a reference to the Output window Build pane"); | |||||
| pane = null; | |||||
| } | |||||
| pane.Activate(); | |||||
| pane.Clear(); | |||||
| } | |||||
| private void WriteToOutputPane(string s) | |||||
| { | |||||
| if (pane != null) | |||||
| pane.OutputString(s); | |||||
| } | |||||
| private static IEnumerable<ProjectItem> ParseProjectItems(object o) | private static IEnumerable<ProjectItem> ParseProjectItems(object o) | ||||
| { | { | ||||
| ProjectItems subitems; | ProjectItems subitems; | ||||
| @@ -267,7 +241,6 @@ namespace Lol.VisualStudio.Plugin | |||||
| } | } | ||||
| private ServiceProvider sp; | private ServiceProvider sp; | ||||
| private IVsOutputWindowPane pane; | |||||
| private List<Project> projects; | private List<Project> projects; | ||||
| } | } | ||||
| @@ -13,11 +13,26 @@ namespace Lol.VisualStudio.Plugin | |||||
| { | { | ||||
| [PackageRegistration(UseManagedResourcesOnly = true)] | [PackageRegistration(UseManagedResourcesOnly = true)] | ||||
| /* LolFx syntax highlighting */ | |||||
| [ProvideServiceAttribute(typeof(LolFxLanguageService), | |||||
| ServiceName = "LolFx Service")] | |||||
| [ProvideLanguageServiceAttribute(typeof(LolFxLanguageService), | |||||
| "LolFx", 106 /* resource ID */, | |||||
| CodeSense = true, | |||||
| RequestStockColors = true, | |||||
| EnableCommenting = true, | |||||
| EnableAsyncCompletion = true)] | |||||
| [ProvideLanguageExtensionAttribute(typeof(LolFxLanguageService), | |||||
| ".lolfx")] | |||||
| [ProvideMenuResource(1000, 1)] | [ProvideMenuResource(1000, 1)] | ||||
| [Guid("f96f7ac5-16ac-4061-8b92-0a02bb455ae9")] | [Guid("f96f7ac5-16ac-4061-8b92-0a02bb455ae9")] | ||||
| [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] | ||||
| [ComVisible(true)] | [ComVisible(true)] | ||||
| [ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")] // This is needed for the package to be autoloaded | |||||
| /* Autoload package */ | |||||
| [ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")] | |||||
| public sealed class PluginPackage : Package | public sealed class PluginPackage : Package | ||||
| { | { | ||||
| public PluginPackage() | public PluginPackage() | ||||
| @@ -32,23 +47,74 @@ namespace Lol.VisualStudio.Plugin | |||||
| Trace.WriteLine(String.Format(CultureInfo.CurrentUICulture, "Entering Initialize() of: {0}", this.ToString())); | Trace.WriteLine(String.Format(CultureInfo.CurrentUICulture, "Entering Initialize() of: {0}", this.ToString())); | ||||
| base.Initialize(); | base.Initialize(); | ||||
| // Ensure the "Build" output pane exists | |||||
| IVsOutputWindow outputWindow = GetService(typeof(SVsOutputWindow)) as IVsOutputWindow; | |||||
| if (null != outputWindow) | |||||
| { | |||||
| Guid guidBuild = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; | |||||
| outputWindow.CreatePane(guidBuild, "Build", 1, 0); | |||||
| } | |||||
| Logger.Initialize(GetService(typeof(SVsOutputWindow)) as IVsOutputWindow); | |||||
| // Register the "Generate Compilers" context menu | |||||
| /* Register the "Generate Compilers" context menu */ | |||||
| OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; | OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; | ||||
| if (null != mcs) | if (null != mcs) | ||||
| { | { | ||||
| CommandID id = new CommandID(GuidsList.guidVsLolCmdSet, VsLolIDList.cmdidGenerateCompilers); | |||||
| CommandID id = new CommandID(GuidsList.guidVsLolCmdSet, | |||||
| VsLolIDList.cmdidGenerateCompilers); | |||||
| OleMenuCommand command = new MenuGenerateCompilers(new ServiceProvider((IOleServiceProvider)this.GetService(typeof(IOleServiceProvider))), id); | OleMenuCommand command = new MenuGenerateCompilers(new ServiceProvider((IOleServiceProvider)this.GetService(typeof(IOleServiceProvider))), id); | ||||
| mcs.AddCommand(command); | mcs.AddCommand(command); | ||||
| } | } | ||||
| /* Register the LolFx language service */ | |||||
| IServiceContainer serviceContainer = this as IServiceContainer; | |||||
| LolFxLanguageService lolfxserv = new LolFxLanguageService(); | |||||
| lolfxserv.SetSite(this); | |||||
| serviceContainer.AddService(typeof(LolFxLanguageService), | |||||
| lolfxserv, true); | |||||
| } | |||||
| } | |||||
| internal static class Logger | |||||
| { | |||||
| public static void Initialize(IVsOutputWindow window) | |||||
| { | |||||
| m_window = window; | |||||
| OpenBuildPane(); | |||||
| if (m_pane == null) | |||||
| Trace.WriteLine("Failed to get a reference to the Output window Build pane"); | |||||
| } | |||||
| private static void OpenBuildPane() | |||||
| { | |||||
| /* Ensure the "Build" output pane exists */ | |||||
| if (m_window != null) | |||||
| { | |||||
| Guid guidBuild = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; | |||||
| m_window.CreatePane(guidBuild, "Build", 1, 0); | |||||
| if (Microsoft.VisualStudio.ErrorHandler.Failed(m_window.GetPane(ref guidBuild, out m_pane))) | |||||
| m_pane = null; | |||||
| } | |||||
| } | } | ||||
| public static void Clear() | |||||
| { | |||||
| OpenBuildPane(); | |||||
| if (m_pane != null) | |||||
| { | |||||
| m_pane.Activate(); | |||||
| m_pane.Clear(); | |||||
| } | |||||
| } | |||||
| public static void Info(string s) | |||||
| { | |||||
| OpenBuildPane(); | |||||
| if (m_pane != null) | |||||
| m_pane.OutputString(s); | |||||
| } | |||||
| private static IVsOutputWindow m_window = null; | |||||
| private static IVsOutputWindowPane m_pane = null; | |||||
| } | } | ||||
| internal static class GuidsList | internal static class GuidsList | ||||
| @@ -70,4 +136,3 @@ namespace Lol.VisualStudio.Plugin | |||||
| public const int cmdidUnused2 = 0x2003; | public const int cmdidUnused2 = 0x2003; | ||||
| } | } | ||||
| } | } | ||||
| @@ -55,6 +55,7 @@ | |||||
| </Reference> | </Reference> | ||||
| <Reference Include="Microsoft.CSharp" /> | <Reference Include="Microsoft.CSharp" /> | ||||
| <Reference Include="Microsoft.VisualStudio.OLE.Interop" /> | <Reference Include="Microsoft.VisualStudio.OLE.Interop" /> | ||||
| <Reference Include="Microsoft.VisualStudio.Package.LanguageService.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | |||||
| <Reference Include="Microsoft.VisualStudio.Shell.Interop" /> | <Reference Include="Microsoft.VisualStudio.Shell.Interop" /> | ||||
| <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" /> | <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" /> | ||||
| <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" /> | <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" /> | ||||
| @@ -64,6 +65,7 @@ | |||||
| <Private>false</Private> | <Private>false</Private> | ||||
| </Reference> | </Reference> | ||||
| <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" /> | <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" /> | ||||
| <Reference Include="Microsoft.VisualStudio.TextManager.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> | |||||
| <Reference Include="System" /> | <Reference Include="System" /> | ||||
| <Reference Include="System.Core" /> | <Reference Include="System.Core" /> | ||||
| <Reference Include="System.Data" /> | <Reference Include="System.Data" /> | ||||
| @@ -73,6 +75,7 @@ | |||||
| <Reference Include="System.Xml" /> | <Reference Include="System.Xml" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Compile Include="LolFxLanguageService.cs" /> | |||||
| <Compile Include="MenuGenerateCompilers.cs" /> | <Compile Include="MenuGenerateCompilers.cs" /> | ||||
| <Compile Include="GlobalSuppressions.cs" /> | <Compile Include="GlobalSuppressions.cs" /> | ||||
| <Compile Include="VsLol.Designer.cs"> | <Compile Include="VsLol.Designer.cs"> | ||||
| @@ -154,4 +157,4 @@ | |||||
| <Target Name="AfterBuild"> | <Target Name="AfterBuild"> | ||||
| </Target> | </Target> | ||||
| --> | --> | ||||
| </Project> | |||||
| </Project> | |||||