Browse Source

vslol: add licensing information to important files.

legacy
Sam Hocevar sam 12 years ago
parent
commit
8ef9d9212c
7 changed files with 620 additions and 517 deletions
  1. +180
    -118
      tools/vslol/CppKeywordClassifier.cs
  2. +107
    -97
      tools/vslol/LolFxLanguageService.cs
  3. +197
    -186
      tools/vslol/MenuGenerateCompilers.cs
  4. +10
    -1
      tools/vslol/Properties/AssemblyInfo.cs
  5. +2
    -2
      tools/vslol/VsLol.Designer.cs
  6. +122
    -111
      tools/vslol/VsLol.cs
  7. +2
    -2
      tools/vslol/VsLol.csproj

+ 180
- 118
tools/vslol/CppKeywordClassifier.cs View File

@@ -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 */

+ 107
- 97
tools/vslol/LolFxLanguageService.cs View File

@@ -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 */

+ 197
- 186
tools/vslol/MenuGenerateCompilers.cs View File

@@ -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 */

+ 10
- 1
tools/vslol/Properties/AssemblyInfo.cs View File

@@ -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;


+ 2
- 2
tools/vslol/VsLol.Designer.cs View File

@@ -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;


+ 122
- 111
tools/vslol/VsLol.cs View File

@@ -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 */

+ 2
- 2
tools/vslol/VsLol.csproj View File

@@ -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>

Loading…
Cancel
Save