| @@ -1,3 +1,13 @@ | |||||
| // | |||||
| // Lol Engine - VsLol add-in for Visual Studio | |||||
| // | |||||
| // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.ComponentModel.Composition; | using System.ComponentModel.Composition; | ||||
| @@ -10,162 +20,214 @@ using Microsoft.VisualStudio.Text.Formatting; | |||||
| using Microsoft.VisualStudio.Language.StandardClassification; | using Microsoft.VisualStudio.Language.StandardClassification; | ||||
| using Microsoft.VisualStudio.Utilities; | using Microsoft.VisualStudio.Utilities; | ||||
| namespace Lol.VisualStudio.Plugin | |||||
| namespace lol | |||||
| { | { | ||||
| [Export(typeof(IClassifierProvider))] | |||||
| [ContentType("c/c++")] | |||||
| [ContentType("csharp")] | |||||
| [ContentType("lolfx")] | |||||
| internal class LolClassifierProvider : IClassifierProvider | |||||
| { | |||||
| [Import] | |||||
| internal IClassificationTypeRegistryService m_type_registry = null; /* Set via MEF */ | |||||
| [Import] | |||||
| internal IClassifierAggregatorService m_aggregator = null; | |||||
| [Import] | |||||
| internal IClassificationFormatMapService m_format_map = null; | |||||
| internal static bool m_inprogress = false; | |||||
| [Export(typeof(IClassifierProvider))] | |||||
| [ContentType("c/c++")] | |||||
| [ContentType("csharp")] | |||||
| [ContentType("lolfx")] | |||||
| internal class LolClassifierProvider : IClassifierProvider | |||||
| { | |||||
| [Import] | |||||
| internal IClassificationTypeRegistryService m_type_registry = null; /* Set via MEF */ | |||||
| [Import] | |||||
| internal IClassifierAggregatorService m_aggregator = null; | |||||
| [Import] | |||||
| internal IClassificationFormatMapService m_format_map = null; | |||||
| public IClassifier GetClassifier(ITextBuffer buffer) | |||||
| { | |||||
| /* Avoid infinite recursion */ | |||||
| if (m_inprogress) | |||||
| return null; | |||||
| internal static bool m_inprogress = false; | |||||
| LolGenericFormat.SetRegistry(m_type_registry, m_format_map); | |||||
| public IClassifier GetClassifier(ITextBuffer buffer) | |||||
| { | |||||
| /* Avoid infinite recursion */ | |||||
| if (m_inprogress) | |||||
| return null; | |||||
| try | |||||
| { | |||||
| m_inprogress = true; | |||||
| return buffer.Properties.GetOrCreateSingletonProperty<CppKeywordClassifier>(delegate { return new CppKeywordClassifier(m_type_registry, m_aggregator.GetClassifier(buffer), buffer.ContentType); }); | |||||
| } | |||||
| finally { m_inprogress = false; } | |||||
| LolGenericFormat.SetRegistry(m_type_registry, m_format_map); | |||||
| try | |||||
| { | |||||
| m_inprogress = true; | |||||
| return buffer.Properties.GetOrCreateSingletonProperty<CppKeywordClassifier>(delegate { return new CppKeywordClassifier(m_type_registry, m_aggregator.GetClassifier(buffer), buffer.ContentType); }); | |||||
| } | } | ||||
| finally { m_inprogress = false; } | |||||
| } | } | ||||
| } | |||||
| class CppKeywordClassifier : IClassifier | |||||
| { | |||||
| private IClassifier m_classifier; | |||||
| class CppKeywordClassifier : IClassifier | |||||
| { | |||||
| private IClassifier m_classifier; | |||||
| private IClassificationType m_customclass_type; | |||||
| private Regex m_customclass_regex; | |||||
| private IClassificationType m_customclass_type, m_constant_type; | |||||
| private Regex m_customclass_regex, m_constant_regex; | |||||
| internal CppKeywordClassifier(IClassificationTypeRegistryService registry, | |||||
| IClassifier classifier, | |||||
| IContentType type) | |||||
| internal CppKeywordClassifier(IClassificationTypeRegistryService registry, | |||||
| IClassifier classifier, | |||||
| IContentType type) | |||||
| { | |||||
| m_classifier = classifier; | |||||
| /* Regex for types and specifiers */ | |||||
| m_customclass_type = registry.GetClassificationType("LolCustomClass"); | |||||
| string tmp = @"\b("; | |||||
| tmp += "void|bool|int|unsigned|char|short|long|float|double|ldouble|"; | |||||
| tmp += "class|struct|union|template|const|static|extern|volatile|inline|namespace|"; | |||||
| if (type.IsOfType("lolfx")) | |||||
| tmp += "attribute|varying|uniform|in|out|"; | |||||
| if (type.IsOfType("csharp")) | |||||
| tmp += "var|out|ref|string|internal|sealed|public|private|protected|override|"; | |||||
| if (!type.IsOfType("csharp")) | |||||
| tmp += "(f(16|128)||d|[ui](8|16||64)|r)(vec[234]|mat[234]|quat|cmplx)|"; | |||||
| if (type.IsOfType("c/c++")) | |||||
| { | { | ||||
| m_classifier = classifier; | |||||
| m_customclass_type = registry.GetClassificationType("LolCustomClass"); | |||||
| string tmp = @"\b("; | |||||
| tmp += "void|bool|int|unsigned|char|short|long|float|double|ldouble|"; | |||||
| tmp += "class|struct|union|template|const|static|extern|volatile|inline|namespace|"; | |||||
| if (type.IsOfType("lolfx")) | |||||
| tmp += "attribute|varying|uniform|in|out|"; | |||||
| if (type.IsOfType("csharp")) | |||||
| tmp += "var|string|internal|sealed|public|private|protected|"; | |||||
| if (!type.IsOfType("csharp")) | |||||
| tmp += "(f(16|128)||d|[ui](8|16||64)|r)(vec[234]|mat[234]|quat|cmplx)|"; | |||||
| if (type.IsOfType("c/c++")) | |||||
| { | |||||
| tmp += "u?int(8|16|32|64|ptr)_t|"; | |||||
| tmp += "real|half|explicit|typename|typedef|"; | |||||
| } | |||||
| tmp = tmp.Remove(tmp.Length - 1); | |||||
| tmp += @")\b"; | |||||
| m_customclass_regex = new Regex(tmp); | |||||
| tmp += "u?int(8|16|32|64|ptr)_t|"; | |||||
| tmp += "(wchar|size|ssize)_t|"; | |||||
| tmp += "real|half|explicit|typename|typedef|auto|"; | |||||
| } | } | ||||
| tmp = tmp.Remove(tmp.Length - 1); | |||||
| tmp += @")\b"; | |||||
| m_customclass_regex = new Regex(tmp); | |||||
| /* Regex for constant words */ | |||||
| m_constant_type = registry.GetClassificationType("LolCppConstant"); | |||||
| if (type.IsOfType("csharp")) | |||||
| m_constant_regex = new Regex(@"\b(null|true|false)\b"); | |||||
| else if (type.IsOfType("c/c++")) | |||||
| m_constant_regex = new Regex(@"\b(NULL|nullptr|true|false|M_PI)\b"); | |||||
| else if (type.IsOfType("lolfx")) | |||||
| m_constant_regex = new Regex(@"\b(gl_Position|gl_FragColor)\b"); | |||||
| else | |||||
| m_constant_regex = new Regex(@"\b(NULL)\b"); | |||||
| } | |||||
| public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span) | |||||
| { | |||||
| List<ClassificationSpan> ret = new List<ClassificationSpan>(); | |||||
| public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span) | |||||
| foreach (ClassificationSpan cs in m_classifier.GetClassificationSpans(span)) | |||||
| { | { | ||||
| List<ClassificationSpan> ret = new List<ClassificationSpan>(); | |||||
| string cs_class = cs.ClassificationType.Classification.ToLower(); | |||||
| foreach (ClassificationSpan cs in m_classifier.GetClassificationSpans(span)) | |||||
| /* Only apply our rules if we found a keyword or an identifier */ | |||||
| if (cs_class == "keyword" || cs_class == "identifier") | |||||
| { | { | ||||
| string cs_class = cs.ClassificationType.Classification.ToLower(); | |||||
| /* Only apply our rules if we found a keyword or an identifier */ | |||||
| if (cs_class == "keyword" || cs_class == "identifier") | |||||
| if (m_customclass_regex.IsMatch(cs.Span.GetText())) | |||||
| { | { | ||||
| if (m_customclass_regex.IsMatch(cs.Span.GetText())) | |||||
| { | |||||
| ret.Add(new ClassificationSpan(cs.Span, m_customclass_type)); | |||||
| continue; | |||||
| } | |||||
| ret.Add(new ClassificationSpan(cs.Span, m_customclass_type)); | |||||
| continue; | |||||
| } | } | ||||
| ret.Add(cs); | |||||
| if (m_constant_regex.IsMatch(cs.Span.GetText())) | |||||
| { | |||||
| ret.Add(new ClassificationSpan(cs.Span, m_constant_type)); | |||||
| continue; | |||||
| } | |||||
| } | } | ||||
| return ret; | |||||
| ret.Add(cs); | |||||
| } | } | ||||
| public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged; | |||||
| return ret; | |||||
| } | } | ||||
| internal class LolGenericFormat : ClassificationFormatDefinition | |||||
| { | |||||
| static IClassificationTypeRegistryService m_type_registry; | |||||
| static IClassificationFormatMapService m_format_map; | |||||
| public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged; | |||||
| } | |||||
| public static void SetRegistry(IClassificationTypeRegistryService type_registry, | |||||
| IClassificationFormatMapService format_map) | |||||
| { | |||||
| m_type_registry = type_registry; | |||||
| m_format_map = format_map; | |||||
| } | |||||
| internal class LolGenericFormat : ClassificationFormatDefinition | |||||
| { | |||||
| static IClassificationTypeRegistryService m_type_registry; | |||||
| static IClassificationFormatMapService m_format_map; | |||||
| protected void CopyStyleColor(string category) | |||||
| { | |||||
| if (m_type_registry == null || m_format_map == null) | |||||
| return; | |||||
| public static void SetRegistry(IClassificationTypeRegistryService type_registry, | |||||
| IClassificationFormatMapService format_map) | |||||
| { | |||||
| m_type_registry = type_registry; | |||||
| m_format_map = format_map; | |||||
| } | |||||
| var map = m_format_map.GetClassificationFormatMap("Text Editor"); | |||||
| if (map == null) | |||||
| return; | |||||
| protected void CopyStyleColor(string category) | |||||
| { | |||||
| if (m_type_registry == null || m_format_map == null) | |||||
| return; | |||||
| var map = m_format_map.GetClassificationFormatMap("Text Editor"); | |||||
| if (map == null) | |||||
| return; | |||||
| //string[] foo = { "Comment", "Keyword", "C/C++ User Keywords", "Call Return", "HTML Comment" , "User Types", "User Types (Type parameters)", "User Types (Value types)"}; | |||||
| //string[] foo = { "Comment", "Keyword", "C/C++ User Keywords", "Call Return", "HTML Comment" , "User Types", "User Types (Type parameters)", "User Types (Value types)"}; | |||||
| var type = m_type_registry.GetClassificationType(category); | |||||
| if (type == null) | |||||
| return; | |||||
| var type = m_type_registry.GetClassificationType(category); | |||||
| if (type == null) | |||||
| return; | |||||
| var prop = map.GetExplicitTextProperties(type); | |||||
| if (prop == null) | |||||
| return; | |||||
| var prop = map.GetExplicitTextProperties(type); | |||||
| if (prop == null) | |||||
| return; | |||||
| var c1 = prop.ForegroundBrush as SolidColorBrush; | |||||
| if (c1 != null && c1.Color != Colors.Transparent) | |||||
| this.ForegroundColor = c1.Color; | |||||
| var c2 = prop.BackgroundBrush as SolidColorBrush; | |||||
| if (c2 != null && c2.Color != Colors.Transparent) | |||||
| this.BackgroundColor = c1.Color; | |||||
| var c1 = prop.ForegroundBrush as SolidColorBrush; | |||||
| if (c1 != null && c1.Color != Colors.Transparent) | |||||
| { | |||||
| this.ForegroundColor = c1.Color; | |||||
| this.ForegroundOpacity = 1.0; | |||||
| } | |||||
| var c2 = prop.BackgroundBrush as SolidColorBrush; | |||||
| if (c2 != null && c2.Color != Colors.Transparent) | |||||
| { | |||||
| this.BackgroundColor = c2.Color; | |||||
| this.BackgroundOpacity = 1.0; | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| internal static class LolClassifierClassificationDefinition | |||||
| internal static class LolClassifierClassificationDefinition | |||||
| { | |||||
| [Export(typeof(ClassificationTypeDefinition))] | |||||
| [Name(LolCppTypeFormat.m_name)] | |||||
| internal static ClassificationTypeDefinition LolCustomClassType = null; | |||||
| [Export(typeof(ClassificationTypeDefinition))] | |||||
| [Name(LolCppConstantFormat.m_name)] | |||||
| internal static ClassificationTypeDefinition LolCustomConstantType = null; | |||||
| } | |||||
| [Export(typeof(EditorFormatDefinition))] | |||||
| [ClassificationType(ClassificationTypeNames = LolCppTypeFormat.m_name)] | |||||
| [Name(LolCppTypeFormat.m_name)] | |||||
| [UserVisible(true)] | |||||
| [Order(After = Priority.Default)] /* Override the Visual Studio classifiers */ | |||||
| internal sealed class LolCppTypeFormat : LolGenericFormat | |||||
| { | |||||
| public const string m_name = "LolCustomClass"; | |||||
| public LolCppTypeFormat() | |||||
| { | { | ||||
| [Export(typeof(ClassificationTypeDefinition))] | |||||
| [Name(LolCppTypeFormat.m_name)] | |||||
| internal static ClassificationTypeDefinition LolCustomClassType = null; | |||||
| this.DisplayName = "C/C++ Types and Qualifiers"; | |||||
| this.ForegroundColor = Colors.Lime; | |||||
| this.ForegroundOpacity = 1.0; | |||||
| this.IsBold = true; | |||||
| //CopyStyleColor("User Types"); | |||||
| } | } | ||||
| } | |||||
| [Export(typeof(EditorFormatDefinition))] | |||||
| [ClassificationType(ClassificationTypeNames = LolCppTypeFormat.m_name)] | |||||
| [Name(LolCppTypeFormat.m_name)] | |||||
| [UserVisible(true)] | |||||
| [Order(After = Priority.Default)] /* Override the Visual Studio classifiers */ | |||||
| internal sealed class LolCppTypeFormat : LolGenericFormat | |||||
| [Export(typeof(EditorFormatDefinition))] | |||||
| [ClassificationType(ClassificationTypeNames = LolCppConstantFormat.m_name)] | |||||
| [Name(LolCppConstantFormat.m_name)] | |||||
| [UserVisible(true)] | |||||
| [Order(After = Priority.Default)] /* Override the Visual Studio classifiers */ | |||||
| internal sealed class LolCppConstantFormat : LolGenericFormat | |||||
| { | |||||
| public const string m_name = "LolCppConstant"; | |||||
| public LolCppConstantFormat() | |||||
| { | { | ||||
| public const string m_name = "LolCustomClass"; | |||||
| public LolCppTypeFormat() | |||||
| { | |||||
| this.DisplayName = "C/C++ Types and Qualifiers"; | |||||
| this.ForegroundColor = Colors.Lime; | |||||
| this.IsBold = true; | |||||
| //CopyStyleColor("User Types"); | |||||
| } | |||||
| this.DisplayName = "C/C++ Constants"; | |||||
| this.ForegroundColor = Colors.Magenta; | |||||
| this.ForegroundOpacity = 1.0; | |||||
| this.IsBold = true; | |||||
| //CopyStyleColor("User Types"); | |||||
| } | } | ||||
| } | } | ||||
| } /* namespace lol */ | |||||
| @@ -1,4 +1,13 @@ | |||||
| using System; | |||||
| // | |||||
| // Lol Engine - VsLol add-in for Visual Studio | |||||
| // | |||||
| // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Text; | using System.Text; | ||||
| @@ -8,130 +17,131 @@ using Microsoft.VisualStudio.Package; | |||||
| using Microsoft.VisualStudio.TextManager.Interop; | using Microsoft.VisualStudio.TextManager.Interop; | ||||
| using Microsoft.VisualStudio.OLE.Interop; | using Microsoft.VisualStudio.OLE.Interop; | ||||
| namespace Lol.VisualStudio.Plugin | |||||
| namespace lol | |||||
| { | |||||
| class LolFxLanguageService : LanguageService | |||||
| { | { | ||||
| class LolFxLanguageService : LanguageService | |||||
| public override string GetFormatFilterList() | |||||
| { | { | ||||
| public override string GetFormatFilterList() | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| public override LanguagePreferences GetLanguagePreferences() | |||||
| public override LanguagePreferences GetLanguagePreferences() | |||||
| { | |||||
| if (m_preferences == null) | |||||
| { | { | ||||
| if (m_preferences == null) | |||||
| { | |||||
| m_preferences = new LanguagePreferences(this.Site, | |||||
| typeof(LolFxLanguageService).GUID, this.Name); | |||||
| m_preferences.Init(); | |||||
| } | |||||
| return m_preferences; | |||||
| m_preferences = new LanguagePreferences(this.Site, | |||||
| typeof(LolFxLanguageService).GUID, this.Name); | |||||
| m_preferences.Init(); | |||||
| } | } | ||||
| return m_preferences; | |||||
| } | |||||
| public override IScanner GetScanner(IVsTextLines buffer) | |||||
| public override IScanner GetScanner(IVsTextLines buffer) | |||||
| { | |||||
| if (m_scanner == null) | |||||
| { | { | ||||
| if (m_scanner == null) | |||||
| { | |||||
| m_scanner = new LolFxScanner(buffer); | |||||
| } | |||||
| return m_scanner; | |||||
| m_scanner = new LolFxScanner(buffer); | |||||
| } | } | ||||
| return m_scanner; | |||||
| } | |||||
| public override string Name | |||||
| { | |||||
| get { return "LolFx"; } | |||||
| } | |||||
| public override string Name | |||||
| { | |||||
| get { return "LolFx"; } | |||||
| } | |||||
| public override AuthoringScope ParseSource(ParseRequest req) | |||||
| { | |||||
| return new LolFxAuthoringScope(); | |||||
| } | |||||
| public override AuthoringScope ParseSource(ParseRequest req) | |||||
| { | |||||
| return new LolFxAuthoringScope(); | |||||
| } | |||||
| private LanguagePreferences m_preferences; | |||||
| private LolFxScanner m_scanner; | |||||
| private LanguagePreferences m_preferences; | |||||
| private LolFxScanner m_scanner; | |||||
| internal class LolFxScanner : IScanner | |||||
| internal class LolFxScanner : IScanner | |||||
| { | |||||
| public LolFxScanner(IVsTextBuffer buffer) | |||||
| { | { | ||||
| public LolFxScanner(IVsTextBuffer buffer) | |||||
| { | |||||
| m_buffer = buffer; | |||||
| } | |||||
| m_buffer = buffer; | |||||
| } | |||||
| bool IScanner.ScanTokenAndProvideInfoAboutIt(TokenInfo tokeninfo, ref int state) | |||||
| bool IScanner.ScanTokenAndProvideInfoAboutIt(TokenInfo tokeninfo, ref int state) | |||||
| { | |||||
| while (m_offset < m_source.Length) | |||||
| { | { | ||||
| 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; | |||||
| } | |||||
| if (m_source[m_offset] == ' ' || m_source[m_offset] == '\t') | |||||
| { | |||||
| ++m_offset; | ++m_offset; | ||||
| ++state; | |||||
| return true; | |||||
| 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; | |||||
| } | } | ||||
| return false; | |||||
| ++m_offset; | |||||
| ++state; | |||||
| return true; | |||||
| } | } | ||||
| enum State | |||||
| { | |||||
| Default, | |||||
| CComment, | |||||
| CppComment, | |||||
| String, | |||||
| } | |||||
| return false; | |||||
| } | |||||
| void IScanner.SetSource(string source, int offset) | |||||
| { | |||||
| m_source = source; | |||||
| m_offset = offset; | |||||
| } | |||||
| enum State | |||||
| { | |||||
| Default, | |||||
| CComment, | |||||
| CppComment, | |||||
| String, | |||||
| } | |||||
| private IVsTextBuffer m_buffer; | |||||
| string m_source; | |||||
| int m_offset; | |||||
| void IScanner.SetSource(string source, int offset) | |||||
| { | |||||
| m_source = source; | |||||
| m_offset = offset; | |||||
| } | } | ||||
| internal class LolFxAuthoringScope : AuthoringScope | |||||
| 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) | |||||
| { | { | ||||
| public override string GetDataTipText(int line, int col, out TextSpan span) | |||||
| { | |||||
| span = new TextSpan(); | |||||
| return null; | |||||
| } | |||||
| span = new TextSpan(); | |||||
| return null; | |||||
| } | |||||
| public override Declarations GetDeclarations(IVsTextView view, | |||||
| int line, | |||||
| int col, | |||||
| TokenInfo info, | |||||
| ParseReason reason) | |||||
| { | |||||
| 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 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; | |||||
| } | |||||
| public override Methods GetMethods(int line, int col, string name) | |||||
| { | |||||
| return null; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } /* namespace lol */ | |||||
| @@ -1,3 +1,13 @@ | |||||
| // | |||||
| // Lol Engine - VsLol add-in for Visual Studio | |||||
| // | |||||
| // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| using System; | using System; | ||||
| using System.Collections; | using System.Collections; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| @@ -15,234 +25,235 @@ using Microsoft.VisualStudio.Shell.Interop; | |||||
| using VSConstants = Microsoft.VisualStudio.VSConstants; | using VSConstants = Microsoft.VisualStudio.VSConstants; | ||||
| namespace Lol.VisualStudio.Plugin | |||||
| namespace lol | |||||
| { | |||||
| internal class MenuGenerateCompilers : OleMenuCommand | |||||
| { | { | ||||
| internal class MenuGenerateCompilers : OleMenuCommand | |||||
| public MenuGenerateCompilers(ServiceProvider sp, CommandID id) : | |||||
| base(new EventHandler(ClickCallback), id, VsLol.ResourceManager.GetString("GenerateCompilersText")) | |||||
| { | { | ||||
| public MenuGenerateCompilers(ServiceProvider sp, CommandID id) : | |||||
| base(new EventHandler(ClickCallback), id, VsLol.ResourceManager.GetString("GenerateCompilersText")) | |||||
| { | |||||
| this.sp = sp; | |||||
| this.projects = new List<Project>(); | |||||
| this.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus); | |||||
| } | |||||
| this.sp = sp; | |||||
| this.projects = new List<Project>(); | |||||
| this.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus); | |||||
| } | |||||
| private void OnBeforeQueryStatus(object sender, EventArgs e) | |||||
| { | |||||
| projects.Clear(); | |||||
| private void OnBeforeQueryStatus(object sender, EventArgs e) | |||||
| { | |||||
| projects.Clear(); | |||||
| var cmd = sender as OleMenuCommand; | |||||
| if (cmd == null) | |||||
| return; | |||||
| var cmd = sender as OleMenuCommand; | |||||
| if (cmd == null) | |||||
| return; | |||||
| IVsMonitorSelection monitorSelection = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection; | |||||
| if (monitorSelection == null) | |||||
| return; | |||||
| IVsMonitorSelection monitorSelection = sp.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection; | |||||
| if (monitorSelection == null) | |||||
| return; | |||||
| IntPtr hier = IntPtr.Zero; | |||||
| UInt32 itemid; | |||||
| IVsMultiItemSelect multiitem = null; | |||||
| IntPtr container = IntPtr.Zero; | |||||
| IntPtr hier = IntPtr.Zero; | |||||
| UInt32 itemid; | |||||
| IVsMultiItemSelect multiitem = null; | |||||
| IntPtr container = IntPtr.Zero; | |||||
| try | |||||
| { | |||||
| monitorSelection.GetCurrentSelection(out hier, out itemid, out multiitem, out container); | |||||
| try | |||||
| { | |||||
| monitorSelection.GetCurrentSelection(out hier, out itemid, out multiitem, out container); | |||||
| /* Bail out if nothing is selected */ | |||||
| if (itemid != VSConstants.VSITEMID_SELECTION && itemid != VSConstants.VSITEMID_NIL) | |||||
| /* Bail out if nothing is selected */ | |||||
| if (itemid != VSConstants.VSITEMID_SELECTION && itemid != VSConstants.VSITEMID_NIL) | |||||
| { | |||||
| if (hier == IntPtr.Zero) | |||||
| { | { | ||||
| if (hier == IntPtr.Zero) | |||||
| { | |||||
| /* FIXME: parse the whole solution */ | |||||
| } | |||||
| else | |||||
| { | |||||
| object project = null; | |||||
| IVsHierarchy hierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(hier); | |||||
| hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out project); | |||||
| projects.Add(project as Project); | |||||
| } | |||||
| /* FIXME: parse the whole solution */ | |||||
| } | } | ||||
| } | |||||
| finally | |||||
| { | |||||
| if (hier != IntPtr.Zero) | |||||
| Marshal.Release(hier); | |||||
| else | |||||
| { | |||||
| object project = null; | |||||
| if (container != IntPtr.Zero) | |||||
| Marshal.Release(container); | |||||
| IVsHierarchy hierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(hier); | |||||
| hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out project); | |||||
| projects.Add(project as Project); | |||||
| } | |||||
| } | } | ||||
| } | |||||
| finally | |||||
| { | |||||
| if (hier != IntPtr.Zero) | |||||
| Marshal.Release(hier); | |||||
| // If there are .l or .y files in this project, display the context menu | |||||
| Visible = false; | |||||
| foreach (Project project in projects) | |||||
| foreach (ProjectItem item in ParseProjectItems(project)) | |||||
| { | |||||
| if (item.Name.EndsWith("-scanner.l") | |||||
| || item.Name.EndsWith("-parser.y")) | |||||
| Visible = true; | |||||
| } | |||||
| if (container != IntPtr.Zero) | |||||
| Marshal.Release(container); | |||||
| } | } | ||||
| private static void ClickCallback(object sender, EventArgs args) | |||||
| // If there are .l or .y files in this project, display the context menu | |||||
| Visible = false; | |||||
| foreach (Project project in projects) | |||||
| foreach (ProjectItem item in ParseProjectItems(project)) | |||||
| { | |||||
| if (item.Name.EndsWith("-scanner.l") | |||||
| || item.Name.EndsWith("-parser.y")) | |||||
| Visible = true; | |||||
| } | |||||
| } | |||||
| private static void ClickCallback(object sender, EventArgs args) | |||||
| { | |||||
| MenuGenerateCompilers cmd = sender as MenuGenerateCompilers; | |||||
| if (cmd == null) | |||||
| return; | |||||
| Logger.Clear(); | |||||
| Logger.Info("------ Build started: Generating Compilers ------\n"); | |||||
| int scanner_count = 0, parser_count = 0, error_count = 0; | |||||
| foreach (Project project in cmd.projects) | |||||
| { | { | ||||
| MenuGenerateCompilers cmd = sender as MenuGenerateCompilers; | |||||
| if (cmd == null) | |||||
| return; | |||||
| Logger.Info("Project " + project.Name + "\n"); | |||||
| string project_path = Path.GetDirectoryName(project.FullName); | |||||
| Logger.Clear(); | |||||
| Logger.Info("------ Build started: Generating Compilers ------\n"); | |||||
| /* FIXME: find this using the solution globals! */ | |||||
| string external_path = project_path; | |||||
| for (int i = 0; i < 10; ++i) | |||||
| { | |||||
| external_path += "\\.."; | |||||
| if (Directory.Exists(external_path + "\\external")) | |||||
| break; | |||||
| } | |||||
| int scanner_count = 0, parser_count = 0, error_count = 0; | |||||
| /* FIXME: do not hardcode shit! */ | |||||
| string flex_path = external_path + "\\external\\flex-2.5.35"; | |||||
| string bison_path = external_path + "\\external\\bison-2.4.2"; | |||||
| foreach (Project project in cmd.projects) | |||||
| /* Workaround for an MSYS bug. If these directories don't | |||||
| * exist, fork() will fail. Yeah, wtf. */ | |||||
| try | |||||
| { | { | ||||
| Logger.Info("Project " + project.Name + "\n"); | |||||
| Directory.CreateDirectory(flex_path + "\\etc"); | |||||
| Directory.CreateDirectory(bison_path + "\\etc"); | |||||
| } | |||||
| catch (Exception e) { } | |||||
| string project_path = Path.GetDirectoryName(project.FullName); | |||||
| // Run flex on all the .l files | |||||
| foreach (ProjectItem item in ParseProjectItems(project)) | |||||
| { | |||||
| string filename = item.get_FileNames(0); | |||||
| /* FIXME: find this using the solution globals! */ | |||||
| string external_path = project_path; | |||||
| for (int i = 0; i < 10; ++i) | |||||
| if (filename.StartsWith(project_path + "\\")) | |||||
| { | { | ||||
| external_path += "\\.."; | |||||
| if (Directory.Exists(external_path + "\\external")) | |||||
| break; | |||||
| filename = filename.Substring(project_path.Length + 1); | |||||
| filename = filename.Replace("\\", "/"); | |||||
| } | } | ||||
| /* FIXME: do not hardcode shit! */ | |||||
| string flex_path = external_path + "\\external\\flex-2.5.35"; | |||||
| string bison_path = external_path + "\\external\\bison-2.4.2"; | |||||
| /* Workaround for an MSYS bug. If these directories don't | |||||
| * exist, fork() will fail. Yeah, wtf. */ | |||||
| try | |||||
| if (item.Name.EndsWith("-scanner.l")) | |||||
| { | { | ||||
| Directory.CreateDirectory(flex_path + "\\etc"); | |||||
| Directory.CreateDirectory(bison_path + "\\etc"); | |||||
| Logger.Info("flex.exe " + filename + "\n"); | |||||
| string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-scanner.l"))); | |||||
| if (!cmd.Run(project_path, | |||||
| flex_path + "\\bin\\flex.exe", | |||||
| "-v -o " | |||||
| + "generated/" + basename + "-scanner.cpp " | |||||
| + filename, | |||||
| "")) | |||||
| ++error_count; | |||||
| ++scanner_count; | |||||
| } | } | ||||
| catch (Exception e) { } | |||||
| // Run flex on all the .l files | |||||
| foreach (ProjectItem item in ParseProjectItems(project)) | |||||
| if (item.Name.EndsWith("-parser.y")) | |||||
| { | { | ||||
| string filename = item.get_FileNames(0); | |||||
| if (filename.StartsWith(project_path + "\\")) | |||||
| { | |||||
| filename = filename.Substring(project_path.Length + 1); | |||||
| filename = filename.Replace("\\", "/"); | |||||
| } | |||||
| if (item.Name.EndsWith("-scanner.l")) | |||||
| { | |||||
| Logger.Info("flex.exe " + filename + "\n"); | |||||
| string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-scanner.l"))); | |||||
| if (!cmd.Run(project_path, | |||||
| flex_path + "\\bin\\flex.exe", | |||||
| "-v -o " | |||||
| + "generated/" + basename + "-scanner.cpp " | |||||
| + filename, | |||||
| "")) | |||||
| ++error_count; | |||||
| ++scanner_count; | |||||
| } | |||||
| if (item.Name.EndsWith("-parser.y")) | |||||
| { | |||||
| Logger.Info("bison.exe " + filename + "\n"); | |||||
| string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-parser.y"))); | |||||
| if (!cmd.Run(project_path, | |||||
| bison_path + "\\bin\\bison.exe", | |||||
| "-v -o " | |||||
| + "generated/" + basename + "-parser.cpp " | |||||
| + "--defines=generated/" + basename + "-parser.h " | |||||
| + "-d " | |||||
| + "-b " | |||||
| + "generated/" + basename + " " | |||||
| + filename, | |||||
| "BISON_PKGDATADIR=" + bison_path + "\\share\\bison")) | |||||
| ++error_count; | |||||
| ++parser_count; | |||||
| } | |||||
| Logger.Info("bison.exe " + filename + "\n"); | |||||
| string basename = Path.GetFileName(filename.Substring(0, filename.LastIndexOf("-parser.y"))); | |||||
| if (!cmd.Run(project_path, | |||||
| bison_path + "\\bin\\bison.exe", | |||||
| "-v -o " | |||||
| + "generated/" + basename + "-parser.cpp " | |||||
| + "--defines=generated/" + basename + "-parser.h " | |||||
| + "-d " | |||||
| + "-b " | |||||
| + "generated/" + basename + " " | |||||
| + filename, | |||||
| "BISON_PKGDATADIR=" + bison_path + "\\share\\bison")) | |||||
| ++error_count; | |||||
| ++parser_count; | |||||
| } | } | ||||
| } | } | ||||
| Logger.Info(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n", | |||||
| scanner_count, parser_count, error_count)); | |||||
| } | } | ||||
| bool Run(string directory, string executable, string arguments, string env) | |||||
| { | |||||
| System.Diagnostics.Process p = new System.Diagnostics.Process(); | |||||
| p.StartInfo.FileName = executable; | |||||
| p.StartInfo.Arguments = arguments; | |||||
| foreach (string s in env.Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries)) | |||||
| { | |||||
| int i = s.IndexOf("="); | |||||
| if (i > 0 && i < s.Length - 1) | |||||
| p.StartInfo.EnvironmentVariables[s.Substring(0, i - 1)] = s.Substring(i + 1); | |||||
| } | |||||
| p.StartInfo.WorkingDirectory = directory; | |||||
| p.StartInfo.CreateNoWindow = true; | |||||
| p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; | |||||
| p.StartInfo.RedirectStandardError = true; | |||||
| p.StartInfo.RedirectStandardOutput = true; | |||||
| p.StartInfo.RedirectStandardInput = true; | |||||
| p.StartInfo.UseShellExecute = false; | |||||
| Logger.Info(string.Format("========== Done: {0} scanner(s), {1} parser(s), {2} error(s) ==========\n", | |||||
| scanner_count, parser_count, error_count)); | |||||
| } | |||||
| try | |||||
| { | |||||
| p.Start(); | |||||
| string output = p.StandardError.ReadToEnd() | |||||
| + p.StandardOutput.ReadToEnd(); | |||||
| p.WaitForExit(); | |||||
| Logger.Info(output); | |||||
| if (p.ExitCode != 0) | |||||
| { | |||||
| Logger.Info("Error: " + executable + " exited with code " + p.ExitCode + "\n"); | |||||
| if (arguments != "") | |||||
| Logger.Info("Error: args: " + arguments + "\n"); | |||||
| if (env != "") | |||||
| Logger.Info("Error: env: " + env + "\n"); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| catch (Exception e) | |||||
| bool Run(string directory, string executable, string arguments, string env) | |||||
| { | |||||
| System.Diagnostics.Process p = new System.Diagnostics.Process(); | |||||
| p.StartInfo.FileName = executable; | |||||
| p.StartInfo.Arguments = arguments; | |||||
| foreach (string s in env.Split(new char[]{'\n'}, StringSplitOptions.RemoveEmptyEntries)) | |||||
| { | |||||
| int i = s.IndexOf("="); | |||||
| if (i > 0 && i < s.Length - 1) | |||||
| p.StartInfo.EnvironmentVariables[s.Substring(0, i - 1)] = s.Substring(i + 1); | |||||
| } | |||||
| p.StartInfo.WorkingDirectory = directory; | |||||
| p.StartInfo.CreateNoWindow = true; | |||||
| p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; | |||||
| p.StartInfo.RedirectStandardError = true; | |||||
| p.StartInfo.RedirectStandardOutput = true; | |||||
| p.StartInfo.RedirectStandardInput = true; | |||||
| p.StartInfo.UseShellExecute = false; | |||||
| try | |||||
| { | |||||
| p.Start(); | |||||
| string output = p.StandardError.ReadToEnd() | |||||
| + p.StandardOutput.ReadToEnd(); | |||||
| p.WaitForExit(); | |||||
| Logger.Info(output); | |||||
| if (p.ExitCode != 0) | |||||
| { | { | ||||
| Logger.Info("Error: failed to launch " + executable + "\n"); | |||||
| Logger.Info("Error: " + executable + " exited with code " + p.ExitCode + "\n"); | |||||
| if (arguments != "") | |||||
| Logger.Info("Error: args: " + arguments + "\n"); | |||||
| if (env != "") | |||||
| Logger.Info("Error: env: " + env + "\n"); | |||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | |||||
| } | } | ||||
| private static IEnumerable<ProjectItem> ParseProjectItems(object o) | |||||
| catch (Exception e) | |||||
| { | { | ||||
| ProjectItems subitems; | |||||
| if (o is Project) | |||||
| { | |||||
| subitems = (o as Project).ProjectItems; | |||||
| } | |||||
| else | |||||
| { | |||||
| yield return (o as ProjectItem); | |||||
| subitems = (o as ProjectItem).ProjectItems; | |||||
| } | |||||
| foreach (ProjectItem item in subitems) | |||||
| foreach (ProjectItem i in ParseProjectItems(item)) | |||||
| yield return i; | |||||
| Logger.Info("Error: failed to launch " + executable + "\n"); | |||||
| return false; | |||||
| } | } | ||||
| private ServiceProvider sp; | |||||
| return true; | |||||
| } | |||||
| private static IEnumerable<ProjectItem> ParseProjectItems(object o) | |||||
| { | |||||
| ProjectItems subitems; | |||||
| if (o is Project) | |||||
| { | |||||
| subitems = (o as Project).ProjectItems; | |||||
| } | |||||
| else | |||||
| { | |||||
| yield return (o as ProjectItem); | |||||
| subitems = (o as ProjectItem).ProjectItems; | |||||
| } | |||||
| private List<Project> projects; | |||||
| foreach (ProjectItem item in subitems) | |||||
| foreach (ProjectItem i in ParseProjectItems(item)) | |||||
| yield return i; | |||||
| } | } | ||||
| private ServiceProvider sp; | |||||
| private List<Project> projects; | |||||
| } | } | ||||
| } /* namespace lol */ | |||||
| @@ -1,4 +1,13 @@ | |||||
| | |||||
| // | |||||
| // Lol Engine - VsLol add-in for Visual Studio | |||||
| // | |||||
| // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| using System.Reflection; | using System.Reflection; | ||||
| using System.Runtime.CompilerServices; | using System.Runtime.CompilerServices; | ||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||
| @@ -8,7 +8,7 @@ | |||||
| // </auto-generated> | // </auto-generated> | ||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
| namespace Lol.VisualStudio.Plugin { | |||||
| namespace lol { | |||||
| using System; | using System; | ||||
| @@ -39,7 +39,7 @@ namespace Lol.VisualStudio.Plugin { | |||||
| internal static global::System.Resources.ResourceManager ResourceManager { | internal static global::System.Resources.ResourceManager ResourceManager { | ||||
| get { | get { | ||||
| if (object.ReferenceEquals(resourceMan, null)) { | if (object.ReferenceEquals(resourceMan, null)) { | ||||
| global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lol.VisualStudio.Plugin.VsLol", typeof(VsLol).Assembly); | |||||
| global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("lol.VsLol", typeof(VsLol).Assembly); | |||||
| resourceMan = temp; | resourceMan = temp; | ||||
| } | } | ||||
| return resourceMan; | return resourceMan; | ||||
| @@ -1,3 +1,13 @@ | |||||
| // | |||||
| // Lol Engine - VsLol add-in for Visual Studio | |||||
| // | |||||
| // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| using System; | using System; | ||||
| using System.ComponentModel.Design; | using System.ComponentModel.Design; | ||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| @@ -9,143 +19,144 @@ using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; | |||||
| using Microsoft.VisualStudio.Shell; | using Microsoft.VisualStudio.Shell; | ||||
| using Microsoft.VisualStudio.Shell.Interop; | using Microsoft.VisualStudio.Shell.Interop; | ||||
| namespace Lol.VisualStudio.Plugin | |||||
| namespace lol | |||||
| { | |||||
| [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)] | |||||
| [Guid("f96f7ac5-16ac-4061-8b92-0a02bb455ae9")] | |||||
| [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] | |||||
| [ComVisible(true)] | |||||
| /* Autoload package */ | |||||
| [ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")] | |||||
| public sealed class PluginPackage : Package | |||||
| { | { | ||||
| [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)] | |||||
| [Guid("f96f7ac5-16ac-4061-8b92-0a02bb455ae9")] | |||||
| [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] | |||||
| [ComVisible(true)] | |||||
| /* Autoload package */ | |||||
| [ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")] | |||||
| public sealed class PluginPackage : Package | |||||
| public PluginPackage() | |||||
| { | { | ||||
| public PluginPackage() | |||||
| { | |||||
| Trace.WriteLine(String.Format(CultureInfo.CurrentUICulture, "Entering constructor for: {0}", this.ToString())); | |||||
| } | |||||
| Trace.WriteLine(String.Format("Entering constructor for: {0}", this.ToString())); | |||||
| } | |||||
| [SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] | |||||
| protected override void Initialize() | |||||
| { | |||||
| // Trace the beginning of this method and call the base implementation. | |||||
| Trace.WriteLine(String.Format("Entering Initialize() of: {0}", this.ToString())); | |||||
| base.Initialize(); | |||||
| Logger.Initialize(GetService(typeof(SVsOutputWindow)) as IVsOutputWindow); | |||||
| [SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] | |||||
| protected override void Initialize() | |||||
| /* Register the "Generate Compilers" context menu */ | |||||
| OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; | |||||
| if (null != mcs) | |||||
| { | { | ||||
| // Trace the beginning of this method and call the base implementation. | |||||
| Trace.WriteLine(String.Format(CultureInfo.CurrentUICulture, "Entering Initialize() of: {0}", this.ToString())); | |||||
| base.Initialize(); | |||||
| Logger.Initialize(GetService(typeof(SVsOutputWindow)) as IVsOutputWindow); | |||||
| /* Register the "Generate Compilers" context menu */ | |||||
| OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; | |||||
| if (null != mcs) | |||||
| { | |||||
| CommandID id = new CommandID(GuidsList.guidVsLolCmdSet, | |||||
| VsLolIDList.cmdidGenerateCompilers); | |||||
| OleMenuCommand command = new MenuGenerateCompilers(new ServiceProvider((IOleServiceProvider)this.GetService(typeof(IOleServiceProvider))), id); | |||||
| 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); | |||||
| CommandID id = new CommandID(GuidsList.guidVsLolCmdSet, | |||||
| VsLolIDList.cmdidGenerateCompilers); | |||||
| OleMenuCommand command = new MenuGenerateCompilers(new ServiceProvider((IOleServiceProvider)this.GetService(typeof(IOleServiceProvider))), id); | |||||
| 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 | |||||
| internal static class Logger | |||||
| { | |||||
| public static void Initialize(IVsOutputWindow window) | |||||
| { | { | ||||
| public static void Initialize(IVsOutputWindow window) | |||||
| { | |||||
| m_window = window; | |||||
| m_window = window; | |||||
| OpenBuildPane(); | |||||
| if (m_pane == null) | |||||
| Trace.WriteLine("Failed to get a reference to the Output window Build pane"); | |||||
| } | |||||
| OpenBuildPane(); | |||||
| 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; | |||||
| } | |||||
| if (m_pane != null) | |||||
| m_pane.Activate(); | |||||
| } | |||||
| if (m_pane == null) | |||||
| Trace.WriteLine("Failed to get a reference to the Output window Build pane"); | |||||
| } | |||||
| public static void Clear() | |||||
| private static void OpenBuildPane() | |||||
| { | |||||
| /* Ensure the "Build" output pane exists */ | |||||
| if (m_window != null) | |||||
| { | { | ||||
| OpenBuildPane(); | |||||
| Guid guidBuild = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; | |||||
| m_window.CreatePane(guidBuild, "Build", 1, 0); | |||||
| if (m_pane == null) | |||||
| { | |||||
| m_backlog = ""; | |||||
| return; | |||||
| } | |||||
| m_pane.Clear(); | |||||
| if (Microsoft.VisualStudio.ErrorHandler.Failed(m_window.GetPane(ref guidBuild, out m_pane))) | |||||
| m_pane = null; | |||||
| } | } | ||||
| public static void Info(string s) | |||||
| { | |||||
| OpenBuildPane(); | |||||
| if (m_pane != null) | |||||
| m_pane.Activate(); | |||||
| } | |||||
| if (m_pane == null) | |||||
| { | |||||
| m_backlog += s; | |||||
| return; | |||||
| } | |||||
| public static void Clear() | |||||
| { | |||||
| OpenBuildPane(); | |||||
| m_pane.OutputString(m_backlog); | |||||
| if (m_pane == null) | |||||
| { | |||||
| m_backlog = ""; | m_backlog = ""; | ||||
| m_pane.OutputString(s); | |||||
| return; | |||||
| } | } | ||||
| private static IVsOutputWindow m_window = null; | |||||
| private static IVsOutputWindowPane m_pane = null; | |||||
| private static string m_backlog = ""; | |||||
| m_pane.Clear(); | |||||
| } | } | ||||
| internal static class GuidsList | |||||
| public static void Info(string s) | |||||
| { | { | ||||
| // Now define the list of guids as public static members. | |||||
| [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] | |||||
| public static readonly Guid guidVsLolPkg = new Guid("{f96f7ac5-16ac-4061-8b92-0a02bb455ae9}"); | |||||
| OpenBuildPane(); | |||||
| public static readonly Guid guidVsLolCmdSet = new Guid("{ce508d12-530e-45d0-8b52-1e9ee3f8eaaf}"); | |||||
| if (m_pane == null) | |||||
| { | |||||
| m_backlog += s; | |||||
| return; | |||||
| } | |||||
| [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] | |||||
| public static readonly Guid guidGearBmp = new Guid("{560dba06-c26b-4731-8229-b816818e5992}"); | |||||
| m_pane.OutputString(m_backlog); | |||||
| m_backlog = ""; | |||||
| m_pane.OutputString(s); | |||||
| } | } | ||||
| internal static class VsLolIDList | |||||
| { | |||||
| public const int cmdidGenerateCompilers = 0x2001; | |||||
| public const int cmdidUnused1 = 0x2002; | |||||
| public const int cmdidUnused2 = 0x2003; | |||||
| } | |||||
| private static IVsOutputWindow m_window = null; | |||||
| private static IVsOutputWindowPane m_pane = null; | |||||
| private static string m_backlog = ""; | |||||
| } | } | ||||
| internal static class GuidsList | |||||
| { | |||||
| // Now define the list of guids as public static members. | |||||
| [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] | |||||
| public static readonly Guid guidVsLolPkg = new Guid("{f96f7ac5-16ac-4061-8b92-0a02bb455ae9}"); | |||||
| public static readonly Guid guidVsLolCmdSet = new Guid("{ce508d12-530e-45d0-8b52-1e9ee3f8eaaf}"); | |||||
| [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] | |||||
| public static readonly Guid guidGearBmp = new Guid("{560dba06-c26b-4731-8229-b816818e5992}"); | |||||
| } | |||||
| internal static class VsLolIDList | |||||
| { | |||||
| public const int cmdidGenerateCompilers = 0x2001; | |||||
| public const int cmdidUnused1 = 0x2002; | |||||
| public const int cmdidUnused2 = 0x2003; | |||||
| } | |||||
| } /* namespace lol */ | |||||
| @@ -8,7 +8,7 @@ | |||||
| <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||||
| <OutputType>Library</OutputType> | <OutputType>Library</OutputType> | ||||
| <AppDesignerFolder>Properties</AppDesignerFolder> | <AppDesignerFolder>Properties</AppDesignerFolder> | ||||
| <RootNamespace>Lol.VisualStudio.Plugin</RootNamespace> | |||||
| <RootNamespace>lol</RootNamespace> | |||||
| <AssemblyName>Lol.VisualStudio.VsLol</AssemblyName> | <AssemblyName>Lol.VisualStudio.VsLol</AssemblyName> | ||||
| <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | ||||
| <PublishUrl>publish\</PublishUrl> | <PublishUrl>publish\</PublishUrl> | ||||
| @@ -168,4 +168,4 @@ | |||||
| <Target Name="AfterBuild"> | <Target Name="AfterBuild"> | ||||
| </Target> | </Target> | ||||
| --> | --> | ||||
| </Project> | |||||
| </Project> | |||||