build: renaming to sourcetrail
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourcetrailPlugin", "SourcetrailPlugin\SourcetrailPlugin.csproj", "{A585A530-E120-4C74-934E-D57ED12A7DA9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,11 @@
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project. Project-level
|
||||
// suppressions either have no target or are given a specific target
|
||||
// and scoped to a namespace, type, member, etc.
|
||||
//
|
||||
// To add a suppression to this file, right-click the message in the
|
||||
// Error List, point to "Suppress Message(s)", and click "In Project
|
||||
// Suppression File". You do not need to add suppressions to this
|
||||
// file manually.
|
||||
|
||||
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
|
||||
@@ -0,0 +1,14 @@
|
||||
// Guids.cs
|
||||
// MUST match guids.h
|
||||
using System;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin
|
||||
{
|
||||
static class GuidList
|
||||
{
|
||||
public const string guidSourcetrailPluginPkgString = "acf15780-03b5-440e-a41e-db79b7043fc2";
|
||||
public const string guidSourcetrailPluginCmdSetString = "0efb005b-715c-4a62-8a9b-1e5a870e6c34";
|
||||
|
||||
public static readonly Guid guidSourcetrailPluginCmdSet = new Guid(guidSourcetrailPluginCmdSetString);
|
||||
};
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
class FileLogger : ILogger
|
||||
{
|
||||
private static string _directory = "";
|
||||
private static string _fileNamePrefix = "Log_SourcetrailPlugin_";
|
||||
private static string _fileNameSufix = ".txt";
|
||||
|
||||
private string _fileName = "";
|
||||
|
||||
private Queue<string> _messageBacklog = new Queue<string>(); // stores messages if the log file was in use at original logging time
|
||||
|
||||
public FileLogger()
|
||||
{
|
||||
DateTime time = DateTime.Now;
|
||||
|
||||
string dateString = "";
|
||||
dateString += time.Year.ToString() + "-" + time.Month.ToString() + "-" + time.Day.ToString() + "_";
|
||||
dateString += time.Hour.ToString() + "-" + time.Minute.ToString() + "-" + time.Second.ToString();
|
||||
|
||||
_fileName = _fileNamePrefix + dateString + _fileNameSufix;
|
||||
|
||||
_directory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
_directory += "\\Coati Software\\Plugins\\VS\\";
|
||||
|
||||
if(System.IO.Directory.Exists(_directory) == false)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(_directory);
|
||||
}
|
||||
}
|
||||
|
||||
public void LogMessage(LogMessage message)
|
||||
{
|
||||
System.IO.StreamWriter writer = null;
|
||||
|
||||
try
|
||||
{
|
||||
writer = System.IO.File.AppendText(_directory + _fileName);
|
||||
|
||||
// write backlog to file first
|
||||
while(_messageBacklog.Count > 0)
|
||||
{
|
||||
string bm = _messageBacklog.Dequeue();
|
||||
writer.WriteLine(bm);
|
||||
}
|
||||
|
||||
writer.WriteLine(message.ToString());
|
||||
writer.Close();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// well...file is still in use
|
||||
_messageBacklog.Enqueue(message.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(writer != null)
|
||||
{
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public interface ILogger
|
||||
{
|
||||
void LogMessage(LogMessage message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class LogManager
|
||||
{
|
||||
private static LogManager _instance = null;
|
||||
|
||||
private List<ILogger> _loggers = new List<ILogger>();
|
||||
|
||||
private bool _loggingEnabled = false;
|
||||
|
||||
public List<ILogger> Loggers
|
||||
{
|
||||
get { return _loggers; }
|
||||
set { _loggers = value; }
|
||||
}
|
||||
|
||||
public bool LoggingEnabled
|
||||
{
|
||||
get { return _loggingEnabled; }
|
||||
set { _loggingEnabled = value; }
|
||||
}
|
||||
|
||||
private LogManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static LogManager GetInstance()
|
||||
{
|
||||
if(_instance == null)
|
||||
{
|
||||
_instance = new LogManager();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public void LogInfo(string message, string sourceFile, string callingFunction, int lineNumber)
|
||||
{
|
||||
LogMessage logMessage = new LogMessage();
|
||||
logMessage.Message = message;
|
||||
logMessage.MessageType = LogMessage.LogMessageType.INFO;
|
||||
logMessage.Time = DateTime.Now;
|
||||
logMessage.SourceFile = sourceFile;
|
||||
logMessage.CallingFunction = callingFunction;
|
||||
logMessage.LineNumber = lineNumber;
|
||||
|
||||
Log(logMessage);
|
||||
}
|
||||
|
||||
public void LogWarning(string message, string sourceFile, string callingFunction, int lineNumber)
|
||||
{
|
||||
LogMessage logMessage = new LogMessage();
|
||||
logMessage.Message = message;
|
||||
logMessage.MessageType = LogMessage.LogMessageType.WARNING;
|
||||
logMessage.Time = DateTime.Now;
|
||||
logMessage.SourceFile = sourceFile;
|
||||
logMessage.CallingFunction = callingFunction;
|
||||
logMessage.LineNumber = lineNumber;
|
||||
|
||||
Log(logMessage);
|
||||
}
|
||||
|
||||
public void LogError(string message, string sourceFile, string callingFunction, int lineNumber)
|
||||
{
|
||||
LogMessage logMessage = new LogMessage();
|
||||
logMessage.Message = message;
|
||||
logMessage.MessageType = LogMessage.LogMessageType.ERROR;
|
||||
logMessage.Time = DateTime.Now;
|
||||
logMessage.SourceFile = sourceFile;
|
||||
logMessage.CallingFunction = callingFunction;
|
||||
logMessage.LineNumber = lineNumber;
|
||||
|
||||
Log(logMessage);
|
||||
}
|
||||
|
||||
private void Log(LogMessage message)
|
||||
{
|
||||
if(_loggingEnabled == true)
|
||||
{
|
||||
foreach (ILogger logger in _loggers)
|
||||
{
|
||||
logger.LogMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class LogMessage
|
||||
{
|
||||
public enum LogMessageType
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR
|
||||
}
|
||||
|
||||
private string _message = "";
|
||||
private DateTime _time = new DateTime();
|
||||
private LogMessageType _messageType = LogMessageType.UNKNOWN;
|
||||
|
||||
private string _sourceFile = "";
|
||||
private string _callingFunction = "";
|
||||
private int _lineNumber = -1;
|
||||
|
||||
public string Message
|
||||
{
|
||||
get { return _message; }
|
||||
set { _message = value; }
|
||||
}
|
||||
|
||||
public DateTime Time
|
||||
{
|
||||
get { return _time; }
|
||||
set { _time = value; }
|
||||
}
|
||||
|
||||
public LogMessageType MessageType
|
||||
{
|
||||
get { return _messageType; }
|
||||
set { _messageType = value; }
|
||||
}
|
||||
|
||||
public string SourceFile
|
||||
{
|
||||
get { return _sourceFile; }
|
||||
set { _sourceFile = value; }
|
||||
}
|
||||
|
||||
public string CallingFunction
|
||||
{
|
||||
get { return _callingFunction; }
|
||||
set { _callingFunction = value; }
|
||||
}
|
||||
|
||||
public int LineNumber
|
||||
{
|
||||
get { return _lineNumber; }
|
||||
set { _lineNumber = value; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = "";
|
||||
|
||||
result += _time.Hour.ToString() + ":" + _time.Minute.ToString() + ":"+ _time.Second.ToString();
|
||||
|
||||
result += "\t";
|
||||
|
||||
result += _messageType.ToString();
|
||||
|
||||
result += "\t";
|
||||
|
||||
result += _sourceFile + ":" + _lineNumber.ToString();
|
||||
|
||||
result += " (";
|
||||
|
||||
result += _callingFunction;
|
||||
|
||||
result += ")";
|
||||
|
||||
result += "\t\t";
|
||||
|
||||
result += _message;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
public class Logging
|
||||
{
|
||||
public static void LogInfo(string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
|
||||
{
|
||||
int idx = file.LastIndexOf('\\');
|
||||
if(idx > -1)
|
||||
{
|
||||
file = file.Substring(idx + 1);
|
||||
}
|
||||
|
||||
LogManager.GetInstance().LogInfo(message, file, member, line);
|
||||
}
|
||||
|
||||
public static void LogWarning(string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
|
||||
{
|
||||
int idx = file.LastIndexOf('\\');
|
||||
if (idx > -1)
|
||||
{
|
||||
file = file.Substring(idx + 1);
|
||||
}
|
||||
|
||||
LogManager.GetInstance().LogWarning(message, file, member, line);
|
||||
}
|
||||
|
||||
public static void LogError(string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
|
||||
{
|
||||
int idx = file.LastIndexOf('\\');
|
||||
if (idx > -1)
|
||||
{
|
||||
file = file.Substring(idx + 1);
|
||||
}
|
||||
|
||||
LogManager.GetInstance().LogError(message, file, member, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging.Obfuscation
|
||||
{
|
||||
class NameObfuscator
|
||||
{
|
||||
private static NameObfuscator _instance = null;
|
||||
|
||||
private Dictionary<string, string> _dictionary = new Dictionary<string, string>();
|
||||
private bool _enabled = false;
|
||||
|
||||
char _currentChar = 'a';
|
||||
int _currentInt = 0;
|
||||
|
||||
private static string _directory = "";
|
||||
private static string _fileNamePrefix = "Dictionary_SourcetrailPlugin_";
|
||||
private static string _fileNameSufix = ".txt";
|
||||
|
||||
private string _fileName = "";
|
||||
|
||||
private Queue<string> _messageBacklog = new Queue<string>(); // stores messages if the log file was in use at original logging time
|
||||
|
||||
private NameObfuscator()
|
||||
{
|
||||
DateTime time = DateTime.Now;
|
||||
|
||||
string dateString = "";
|
||||
dateString += time.Year.ToString() + "-" + time.Month.ToString() + "-" + time.Day.ToString() + "_";
|
||||
dateString += time.Hour.ToString() + "-" + time.Minute.ToString() + "-" + time.Second.ToString();
|
||||
|
||||
_fileName = _fileNamePrefix + dateString + _fileNameSufix;
|
||||
|
||||
_directory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
_directory += "\\Coati Software\\Plugins\\VS\\";
|
||||
|
||||
if (System.IO.Directory.Exists(_directory) == false)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(_directory);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new NameObfuscator();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetObfuscatedName(string originalName)
|
||||
{
|
||||
CreateInstance();
|
||||
|
||||
if (_instance._enabled)
|
||||
{
|
||||
if (_instance._dictionary.ContainsKey(originalName))
|
||||
{
|
||||
return _instance._dictionary[originalName];
|
||||
}
|
||||
else
|
||||
{
|
||||
string newName = _instance.GetNewName();
|
||||
_instance._dictionary[originalName] = newName;
|
||||
|
||||
_instance.WriteDictionaryEntryToFile(newName, originalName); // key and value reversed because that's the way the dictionary file is to be used...
|
||||
return newName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return originalName;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Enabled(bool enabled)
|
||||
{
|
||||
CreateInstance();
|
||||
|
||||
_instance._enabled = enabled;
|
||||
}
|
||||
|
||||
private string GetNewName()
|
||||
{
|
||||
string name = "";
|
||||
|
||||
name = _currentChar.ToString() + _currentInt.ToString();
|
||||
|
||||
++_currentChar;
|
||||
|
||||
if((int)_currentChar > 122)
|
||||
{
|
||||
_currentChar = 'a';
|
||||
++_currentInt;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private void WriteDictionaryEntryToFile(string key, string value)
|
||||
{
|
||||
System.IO.StreamWriter writer = null;
|
||||
string message = key + " - " + value;
|
||||
|
||||
try
|
||||
{
|
||||
writer = System.IO.File.AppendText(_directory + _fileName);
|
||||
|
||||
// write backlog to file first
|
||||
while (_messageBacklog.Count > 0)
|
||||
{
|
||||
string bm = _messageBacklog.Dequeue();
|
||||
writer.WriteLine(bm);
|
||||
}
|
||||
|
||||
writer.WriteLine(message.ToString());
|
||||
writer.Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// well...file is still in use
|
||||
_messageBacklog.Enqueue(message.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (writer != null)
|
||||
{
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using EnvDTE;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Logging
|
||||
{
|
||||
class VSOutputLogger : ILogger
|
||||
{
|
||||
private EnvDTE.DTE _dte = null;
|
||||
private OutputWindowPane _pane = null;
|
||||
|
||||
public VSOutputLogger(EnvDTE.DTE dte)
|
||||
{
|
||||
_dte = dte;
|
||||
}
|
||||
|
||||
public void LogMessage(LogMessage message)
|
||||
{
|
||||
if (message.MessageType == SourcetrailPlugin.Logging.LogMessage.LogMessageType.INFO)
|
||||
{
|
||||
Debug.WriteLine(message.Message, "Info");
|
||||
WriteToOutputWindow("Info: " + message.Message);
|
||||
}
|
||||
if (message.MessageType == SourcetrailPlugin.Logging.LogMessage.LogMessageType.WARNING)
|
||||
{
|
||||
Debug.WriteLine(message.Message, "Warning");
|
||||
WriteToOutputWindow("Warning: " + message.Message);
|
||||
}
|
||||
if (message.MessageType == SourcetrailPlugin.Logging.LogMessage.LogMessageType.ERROR)
|
||||
{
|
||||
Debug.WriteLine(message.Message, "Error");
|
||||
WriteToOutputWindow("Error: " + message.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteToOutputWindow(string message)
|
||||
{
|
||||
string paneName = "Sourcetrail Log";
|
||||
|
||||
if (_dte.Windows.Count > 0)
|
||||
{
|
||||
Window window = _dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
|
||||
OutputWindow outputWindow = (OutputWindow)window.Object;
|
||||
|
||||
OutputWindowPanes panes = outputWindow.OutputWindowPanes;
|
||||
|
||||
if(_pane == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < panes.Count; i++)
|
||||
{
|
||||
OutputWindowPane pane = panes.Item(i);
|
||||
|
||||
if (pane.Name.Equals(paneName, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
_pane = outputWindow.OutputWindowPanes.Item(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (_pane == null)
|
||||
{
|
||||
_pane = outputWindow.OutputWindowPanes.Add(paneName);
|
||||
}
|
||||
|
||||
_pane.OutputString(message + '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// based on: https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Multitasking
|
||||
{
|
||||
class LimitedThreadsTaskScheduler : TaskScheduler
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static bool _currentThreadIsProcessingItems;
|
||||
|
||||
private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
|
||||
|
||||
private readonly int _maxNumberOfRunningThreads = 0;
|
||||
|
||||
private int _delegatesQueuedOrRunning = 0;
|
||||
|
||||
public LimitedThreadsTaskScheduler(int maxNumberOfRunningThreads)
|
||||
{
|
||||
if (maxNumberOfRunningThreads < 1)
|
||||
{
|
||||
maxNumberOfRunningThreads = 1;
|
||||
}
|
||||
|
||||
_maxNumberOfRunningThreads = maxNumberOfRunningThreads;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Task> GetScheduledTasks()
|
||||
{
|
||||
bool lockTaken = false;
|
||||
|
||||
try
|
||||
{
|
||||
Monitor.TryEnter(_tasks, ref lockTaken);
|
||||
if(lockTaken)
|
||||
{
|
||||
return _tasks;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockTaken)
|
||||
{
|
||||
Monitor.Exit(_tasks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void QueueTask(Task task)
|
||||
{
|
||||
lock(_tasks)
|
||||
{
|
||||
_tasks.AddLast(task);
|
||||
|
||||
if(_delegatesQueuedOrRunning < _maxNumberOfRunningThreads)
|
||||
{
|
||||
++_delegatesQueuedOrRunning;
|
||||
NotifyThreadPoolOfPendingWork();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
|
||||
{
|
||||
if(!_currentThreadIsProcessingItems)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(taskWasPreviouslyQueued)
|
||||
{
|
||||
if(TryDequeue(task))
|
||||
{
|
||||
return base.TryExecuteTask(task);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.TryExecuteTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
private void NotifyThreadPoolOfPendingWork()
|
||||
{
|
||||
ThreadPool.UnsafeQueueUserWorkItem(_ =>
|
||||
{
|
||||
_currentThreadIsProcessingItems = true;
|
||||
try
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
Task item;
|
||||
|
||||
lock(_tasks)
|
||||
{
|
||||
if(_tasks.Count <= 0)
|
||||
{
|
||||
--_delegatesQueuedOrRunning;
|
||||
break;
|
||||
}
|
||||
|
||||
item = _tasks.First.Value;
|
||||
_tasks.RemoveFirst();
|
||||
}
|
||||
|
||||
base.TryExecuteTask(item);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_currentThreadIsProcessingItems = false;
|
||||
}
|
||||
|
||||
}, null);
|
||||
}
|
||||
|
||||
protected sealed override bool TryDequeue(Task task)
|
||||
{
|
||||
lock(_tasks)
|
||||
{
|
||||
return _tasks.Remove(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// PkgCmdID.cs
|
||||
// MUST match PkgCmdID.h
|
||||
using System;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin
|
||||
{
|
||||
static class PkgCmdIDList
|
||||
{
|
||||
public const uint cmdidSourcetrailSetActiveToken = 0x104;
|
||||
public const uint cmdidSourcetrailCreateProject = 0x105;
|
||||
public const uint cmdidSourcetrailCreateCDB = 0x106;
|
||||
public const uint cmdidSourcetrailOpenLogFolder = 0x107;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SourcetrailPlugin")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Coati Software")]
|
||||
[assembly: AssemblyProduct("SourcetrailPlugin")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: CLSCompliant(false)]
|
||||
[assembly: NeutralResourcesLanguage("en-US")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CoatiSoftware.SourcetrailPlugin.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
VS SDK Notes: This resx file contains the resources that will be consumed directly by your package.
|
||||
For example, if you chose to create a tool window, there is a resource with ID 'CanNotCreateWindow'. This
|
||||
is used in VsPkg.cs to determine the string to show the user if there is an error when attempting to create
|
||||
the tool window.
|
||||
|
||||
Resources that are accessed directly from your package *by Visual Studio* are stored in the VSPackage.resx
|
||||
file.
|
||||
-->
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.SolutionParser
|
||||
{
|
||||
public class CommandObject
|
||||
{
|
||||
private string _file = "";
|
||||
private string _directory = "";
|
||||
private string _command = "";
|
||||
|
||||
public string File
|
||||
{
|
||||
get { return _file; }
|
||||
set
|
||||
{
|
||||
_file = value;
|
||||
//_file = _file.Replace('"', '\'');
|
||||
//_file = _file.Replace('\"', '\'');
|
||||
//_file = _file.Replace("\\\"", "'");
|
||||
}
|
||||
}
|
||||
|
||||
public string Directory
|
||||
{
|
||||
get { return _directory; }
|
||||
set { _directory = value; }
|
||||
}
|
||||
|
||||
public string Command
|
||||
{
|
||||
get { return _command; }
|
||||
set
|
||||
{
|
||||
_command = value;
|
||||
//_command = _command.Replace('"', '\'');
|
||||
//_command = _command.Replace("\"", "'");
|
||||
//_command = _command.Replace("\\\"", "'");
|
||||
}
|
||||
}
|
||||
|
||||
public string SerializeJSON()
|
||||
{
|
||||
string result = "\t{\n";
|
||||
|
||||
result += "\t\t\"directory\": \"" + Directory + "\",\n";
|
||||
result += "\t\t\"command\": \"" + Command + "\",\n";
|
||||
result += "\t\t\"file\": \"" + File + "\"\n";
|
||||
|
||||
result += "\t}";
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
+351
@@ -0,0 +1,351 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.SolutionParser
|
||||
{
|
||||
public class CompilationDatabase
|
||||
{
|
||||
private List<CommandObject> _commandObjects = new List<CommandObject>();
|
||||
|
||||
// meta data
|
||||
private string _name = "";
|
||||
private string _sourceProject = "";
|
||||
private string _directory = "";
|
||||
|
||||
private System.DateTime _lastUpdated = new System.DateTime();
|
||||
|
||||
private List<string> _includedProjects = new List<string>();
|
||||
private string _configurationName = "";
|
||||
private string _platformName = "";
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
public string SourceProject
|
||||
{
|
||||
get { return _sourceProject; }
|
||||
set { _sourceProject = value; }
|
||||
}
|
||||
|
||||
public string Directory
|
||||
{
|
||||
get { return _directory; }
|
||||
set { _directory = value; }
|
||||
}
|
||||
|
||||
public System.DateTime LastUpdated
|
||||
{
|
||||
get { return _lastUpdated; }
|
||||
set { _lastUpdated = value; }
|
||||
}
|
||||
|
||||
public List<string> IncludedProjects
|
||||
{
|
||||
get { return _includedProjects; }
|
||||
set { _includedProjects = value; }
|
||||
}
|
||||
|
||||
public string ConfigurationName
|
||||
{
|
||||
get { return _configurationName; }
|
||||
set { _configurationName = value; }
|
||||
}
|
||||
|
||||
public string PlatformName
|
||||
{
|
||||
get { return _platformName; }
|
||||
set { _platformName = value; }
|
||||
}
|
||||
|
||||
public int CommandObjectCount
|
||||
{
|
||||
get { return _commandObjects.Count; }
|
||||
}
|
||||
|
||||
public void AddOrUpdateCommandObject(CommandObject commandObject, bool saveImmediatly = false)
|
||||
{
|
||||
_commandObjects.Add(commandObject); // updating is not efficient as it is
|
||||
}
|
||||
|
||||
// remove commandObjects for removed files
|
||||
public void Clean()
|
||||
{
|
||||
for (int i = 0; i < _commandObjects.Count; i++)
|
||||
{
|
||||
if (System.IO.File.Exists(_commandObjects[i].File) == false)
|
||||
{
|
||||
_commandObjects.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCommandObjects()
|
||||
{
|
||||
_commandObjects.Clear();
|
||||
}
|
||||
|
||||
public bool CheckCDBExists()
|
||||
{
|
||||
if (_directory.Length > 0 && _name.Length > 0)
|
||||
{
|
||||
string path = GetFilePath();
|
||||
|
||||
if(System.IO.File.Exists(path) == false)
|
||||
{
|
||||
_lastUpdated = System.DateTime.MinValue; // if file is missing, set date way back so it doesn't interfere with re-building
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogWarning("Can't check cdb data, directory and/or name has not been set: directory - '" + _directory + "', name - '" + _name + "'");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryLoadData()
|
||||
{
|
||||
if(_directory.Length > 0 && _name.Length > 0)
|
||||
{
|
||||
string path = GetFilePath();
|
||||
|
||||
if(System.IO.File.Exists(path))
|
||||
{
|
||||
string data = "";
|
||||
|
||||
using (System.IO.StreamReader file = new System.IO.StreamReader(path))
|
||||
{
|
||||
string line = "";
|
||||
|
||||
while ((line = file.ReadLine()) != null)
|
||||
{
|
||||
data += line;
|
||||
}
|
||||
}
|
||||
|
||||
DeserializeJSON(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastUpdated = System.DateTime.MinValue; // if file is missing, set date way back so it doesn't interfere with re-building
|
||||
|
||||
Logging.Logging.LogError("The cdb file '" + path + "' does not exist.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogWarning("Can't load cdb data, directory and/or name has not been set: directory - '" + _directory + "', name - '" + _name + "'");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UnloadData()
|
||||
{
|
||||
_commandObjects.Clear();
|
||||
}
|
||||
|
||||
public string SerializeJSON()
|
||||
{
|
||||
string result = "[\n";
|
||||
|
||||
foreach(CommandObject cm in _commandObjects)
|
||||
{
|
||||
result += cm.SerializeJSON() + ",";
|
||||
}
|
||||
|
||||
result += "\n]";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void DeserializeJSON(string jsonCDB)
|
||||
{
|
||||
if(jsonCDB.Length > 0)
|
||||
{
|
||||
JArray commandObjects = JArray.Parse(jsonCDB);
|
||||
|
||||
_commandObjects.Clear();
|
||||
|
||||
foreach (JObject o in commandObjects.Children<JObject>())
|
||||
{
|
||||
CommandObject co = new CommandObject();
|
||||
|
||||
string directory = o.Property("directory").Value.ToString();
|
||||
string command = o.Property("command").Value.ToString();
|
||||
string file = o.Property("file").Value.ToString();
|
||||
|
||||
co.Directory = directory;
|
||||
co.Command = command;
|
||||
co.File = file;
|
||||
|
||||
_commandObjects.Add(co);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public XmlNode GetMetaDataXML(XmlDocument doc)
|
||||
{
|
||||
// XmlDocument doc = new XmlDocument();
|
||||
XmlNode root = doc.CreateElement("cdb");
|
||||
|
||||
XmlElement name = doc.CreateElement("name");
|
||||
name.InnerText = _name;
|
||||
|
||||
XmlElement sourceProject = doc.CreateElement("sourceProject");
|
||||
sourceProject.InnerText = _sourceProject;
|
||||
|
||||
XmlElement directory = doc.CreateElement("directory");
|
||||
directory.InnerText = _directory;
|
||||
|
||||
XmlElement lastUpdated = doc.CreateElement("lastUpdated");
|
||||
lastUpdated.InnerText = _lastUpdated.ToString();
|
||||
|
||||
XmlElement includedProjects = doc.CreateElement("includedProjects");
|
||||
foreach (string project in _includedProjects)
|
||||
{
|
||||
XmlElement includedProject = doc.CreateElement("includedProject");
|
||||
includedProject.InnerText = project;
|
||||
includedProjects.AppendChild(includedProject);
|
||||
}
|
||||
|
||||
XmlElement configuration = doc.CreateElement("configuration");
|
||||
configuration.InnerText = _configurationName;
|
||||
|
||||
XmlElement platform = doc.CreateElement("platform");
|
||||
platform.InnerText = _platformName;
|
||||
|
||||
root.AppendChild(name);
|
||||
root.AppendChild(sourceProject);
|
||||
root.AppendChild(directory);
|
||||
root.AppendChild(lastUpdated);
|
||||
root.AppendChild(includedProjects);
|
||||
root.AppendChild(configuration);
|
||||
root.AppendChild(platform);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public string SerializeMetaDataXML()
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
XmlNode root = GetMetaDataXML(doc);
|
||||
|
||||
System.IO.StringWriter writer = new System.IO.StringWriter();
|
||||
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(XmlElement));
|
||||
serializer.Serialize(writer, root);
|
||||
|
||||
return writer.ToString();
|
||||
}
|
||||
|
||||
public static List<CompilationDatabase> ParseCDBsMetaData(string data)
|
||||
{
|
||||
List<CompilationDatabase> cdbs = new List<CompilationDatabase>();
|
||||
|
||||
if(data.Length > 0)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.LoadXml(data);
|
||||
XmlNode root = doc.SelectSingleNode("cdbs");
|
||||
|
||||
XmlNodeList nodes = root.SelectNodes("cdb");
|
||||
|
||||
foreach (XmlNode node in nodes)
|
||||
{
|
||||
cdbs.Add(ParseCDBMetaData(node));
|
||||
}
|
||||
}
|
||||
|
||||
return cdbs;
|
||||
}
|
||||
|
||||
public static CompilationDatabase ParseCDBMetaData(XmlNode node)
|
||||
{
|
||||
CompilationDatabase cdb = new CompilationDatabase();
|
||||
|
||||
XmlNode nameNode = node.SelectSingleNode("name");
|
||||
string name = nameNode.InnerText;
|
||||
|
||||
XmlNode sourceNode = node.SelectSingleNode("sourceProject");
|
||||
string source = sourceNode.InnerText;
|
||||
|
||||
XmlNode directoryNode = node.SelectSingleNode("directory");
|
||||
string directory = directoryNode.InnerText;
|
||||
|
||||
XmlNode updatedNode = node.SelectSingleNode("lastUpdated");
|
||||
string updated = updatedNode.InnerText;
|
||||
System.DateTime updatedDate;
|
||||
if(System.DateTime.TryParse(updated, out updatedDate) == false)
|
||||
{
|
||||
updatedDate = System.DateTime.MinValue;
|
||||
}
|
||||
|
||||
XmlNode includedProjects = node.SelectSingleNode("includedProjects");
|
||||
XmlNodeList includedProjectNodes = includedProjects.SelectNodes("includedProject");
|
||||
List<string> includedProjectsList = new List<string>();
|
||||
foreach(XmlNode p in includedProjectNodes)
|
||||
{
|
||||
includedProjectsList.Add(p.InnerText);
|
||||
}
|
||||
|
||||
XmlNode configurationNode = node.SelectSingleNode("configuration");
|
||||
string configuration = configurationNode.InnerText;
|
||||
|
||||
XmlNode platformNode = node.SelectSingleNode("platform");
|
||||
string platform = platformNode.InnerText;
|
||||
|
||||
// if cdb file is not there anymore, set the modified date back so that a full update will be performed
|
||||
if(System.IO.File.Exists(directory + "\\" + name + ".json") == false)
|
||||
{
|
||||
updatedDate = System.DateTime.MinValue;
|
||||
}
|
||||
|
||||
cdb.Name = name;
|
||||
cdb.SourceProject = source;
|
||||
cdb.Directory = directory;
|
||||
cdb.LastUpdated = updatedDate;
|
||||
cdb.IncludedProjects = includedProjectsList;
|
||||
cdb.ConfigurationName = configuration;
|
||||
cdb.PlatformName = platform;
|
||||
|
||||
return cdb;
|
||||
}
|
||||
|
||||
private bool TryUpdateCommandObject(CommandObject co)
|
||||
{
|
||||
CommandObject old = _commandObjects.Find(x => x.File == co.File);
|
||||
|
||||
if(old != null)
|
||||
{
|
||||
_commandObjects.Remove(old);
|
||||
_commandObjects.Add(co);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetFilePath()
|
||||
{
|
||||
return _directory + "\\" + _name + ".json";
|
||||
}
|
||||
}
|
||||
}
|
||||
+691
@@ -0,0 +1,691 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EnvDTE;
|
||||
|
||||
using Microsoft.VisualStudio.VCProjectEngine;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.SolutionParser
|
||||
{
|
||||
class SolutionParser
|
||||
{
|
||||
static private List<Guid> _reloadedProjectGuids = new List<Guid>();
|
||||
static private List<string> _compatibilityFlags = new List<string>() { "-fms-extensions", "-fms-compatibility" };
|
||||
static private string _compatibilityVersionFlagBase = "-fms-compatibility-version="; // I want to get the exact version at runtime for this flag, therefore I keep it seperate from the others to make things a bit easier...
|
||||
static private string _compatibilityVersionFlag = _compatibilityVersionFlagBase + "19"; // This default version would correspond to VS2015
|
||||
|
||||
static public List<string> _additionalCompileFlags = new List<string>();
|
||||
|
||||
static public List<string> _headerDirectories = new List<string>();
|
||||
|
||||
static private List<string> _extensionWhiteList = new List<string>() { "c", "cc", "cpp", "cxx", "C", "h", "hpp" };
|
||||
|
||||
public static List<CommandObject> CreateCommandObjects(Project project, string configurationName, string platformName, string cStandard)
|
||||
{
|
||||
Logging.Logging.LogInfo("Creating command objects from project " + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name));
|
||||
|
||||
List<CommandObject> result = new List<CommandObject>();
|
||||
|
||||
DTE dte = project.DTE;
|
||||
Guid projectGuid = Utility.ProjectUtility.ReloadProject(project);
|
||||
|
||||
VCProject vcProject = project.Object as VCProject;
|
||||
|
||||
if (vcProject == null)
|
||||
{
|
||||
Logging.Logging.LogWarning("Project '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "' could not be converted to VCProject, skipping.");
|
||||
return result;
|
||||
}
|
||||
|
||||
SetCompatibilityVersionFlag(vcProject, configurationName, platformName);
|
||||
|
||||
// gather include paths and preprocessor definitions of the project
|
||||
List<string> includeDirectories = new List<string>();
|
||||
List<string> preprocessorDefinitions = new List<string>();
|
||||
|
||||
Tuple<List<string>, List<string>> pathsAndFlags = GetProjectIncludeDirectoriesAndPreprocessorDefs(vcProject, configurationName, platformName);
|
||||
|
||||
includeDirectories = pathsAndFlags.Item1;
|
||||
preprocessorDefinitions = pathsAndFlags.Item2;
|
||||
|
||||
// create command objects for all applicable project items
|
||||
List<ProjectItem> projectItems = Utility.ProjectUtility.GetProjectItems(project);
|
||||
|
||||
VCConfiguration vcProjectConfig = GetProjectConfiguration(vcProject, configurationName, platformName);
|
||||
string cppStandard = GetCppStandardString(vcProjectConfig);
|
||||
|
||||
Logging.Logging.LogInfo("Found C++ standard " + cppStandard + ".");
|
||||
|
||||
foreach (EnvDTE.ProjectItem item in projectItems)
|
||||
{
|
||||
CommandObject cmdObj = CreateCommandObject(item, includeDirectories, preprocessorDefinitions, cppStandard, cStandard, configurationName, platformName);
|
||||
if (cmdObj != null)
|
||||
{
|
||||
result.Add(cmdObj);
|
||||
}
|
||||
}
|
||||
|
||||
if (projectGuid != Guid.Empty)
|
||||
{
|
||||
Utility.ProjectUtility.UnloadProject(projectGuid, dte);
|
||||
}
|
||||
|
||||
_headerDirectories = _headerDirectories.Distinct().ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static private Tuple<List<string>, List<string>> GetProjectIncludeDirectoriesAndPreprocessorDefs(VCProject project, string configurationName, string platformName)
|
||||
{
|
||||
Logging.Logging.LogInfo("Attempting to retreive Include Directories and Preprocessor Definitions for project '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "'");
|
||||
|
||||
List<string> includeDirectories = new List<string>();
|
||||
List<string> preprocessorDefinitions = new List<string>();
|
||||
|
||||
VCConfiguration vcProjectConfig = null;
|
||||
try
|
||||
{
|
||||
vcProjectConfig = GetProjectConfiguration(project, configurationName, platformName);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to retreive project configuration: " + e.Message);
|
||||
}
|
||||
|
||||
if (vcProjectConfig != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// get additional include directories
|
||||
// source: http://www.mztools.com/articles/2014/MZ2014005.aspx
|
||||
IEnumerable projectTools = vcProjectConfig.Tools as IEnumerable;
|
||||
foreach (Object tool in projectTools)
|
||||
{
|
||||
VCCLCompilerTool compilerTool = tool as VCCLCompilerTool;
|
||||
|
||||
if (compilerTool != null)
|
||||
{
|
||||
string additionalIncludeDirs = compilerTool.FullIncludePath;
|
||||
string preprocessorDefinition = compilerTool.PreprocessorDefinitions;
|
||||
|
||||
string[] prepDefs = preprocessorDefinition.Split(';');
|
||||
|
||||
foreach (string prepDef in prepDefs)
|
||||
{
|
||||
preprocessorDefinitions.Add(prepDef);
|
||||
}
|
||||
|
||||
string[] directories = additionalIncludeDirs.Split(';');
|
||||
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
if (directory.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string dir = directory;
|
||||
|
||||
// In case of a project-relative path
|
||||
if (directory.Length > 0 && directory.Substring(0, 1) == ".")
|
||||
{
|
||||
dir = project.ProjectDirectory + directory;
|
||||
}
|
||||
|
||||
// make it canonical
|
||||
dir = new Uri(dir).LocalPath;
|
||||
|
||||
includeDirectories.Add(dir);
|
||||
}
|
||||
|
||||
break; // TODO: find some documentation on why the break is needed
|
||||
// Apparently only the first 'tool' is needed, but why?
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to retreive include directories: " + e.Message);
|
||||
return new Tuple<List<string>, List<string>>(new List<string>(), new List<string>());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
VCPlatform platform = vcProjectConfig.Platform as VCPlatform;
|
||||
string platformIncludeDirectories = platform.IncludeDirectories;
|
||||
string[] seperatedDirectories = platformIncludeDirectories.Split(';');
|
||||
|
||||
foreach (string directory in seperatedDirectories)
|
||||
{
|
||||
string resolvedDirectory = ResolveVSMacro(vcProjectConfig, directory);
|
||||
string[] splitResolvedDirectory = resolvedDirectory.Split(';'); // resolved macros might result in concatenated paths
|
||||
|
||||
foreach (string p in splitResolvedDirectory)
|
||||
{
|
||||
includeDirectories.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
return new Tuple<List<string>, List<string>>(new List<string>(), new List<string>());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogWarning("Could not retreive Project Configuration. No include directories or preprocessor definitions could be retreived.");
|
||||
return new Tuple<List<string>, List<string>>(new List<string>(), new List<string>());
|
||||
}
|
||||
|
||||
includeDirectories = includeDirectories.Distinct().ToList();
|
||||
|
||||
preprocessorDefinitions = preprocessorDefinitions.Distinct().ToList();
|
||||
|
||||
Logging.Logging.LogInfo("Found " + includeDirectories.Count.ToString() + " distinct include directories and " + preprocessorDefinitions.Count.ToString() + " distinct preprocessor definitions.");
|
||||
Logging.Logging.LogInfo("Attempting to resolve and clean up.");
|
||||
|
||||
for (int i = 0; i < includeDirectories.Count; i++)
|
||||
{
|
||||
string path = includeDirectories.ElementAt(i).Replace("\\", "/"); // backslashes would cause some string-escaping hassles...
|
||||
|
||||
bool exists = true;
|
||||
if (System.IO.Directory.Exists(path) == false)
|
||||
{
|
||||
exists = false;
|
||||
}
|
||||
|
||||
// could be a relative path...
|
||||
if (exists == false)
|
||||
{
|
||||
if (System.IO.Directory.Exists(project.ProjectDirectory + path) == false)
|
||||
{
|
||||
exists = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = project.ProjectDirectory + path;
|
||||
path = path.Replace("\\", "/");
|
||||
exists = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (exists == false)
|
||||
{
|
||||
includeDirectories.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
includeDirectories[i] = path;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Logging.LogInfo("Found " + includeDirectories.Count.ToString() + " include directories and " + preprocessorDefinitions.Count.ToString() + " preprocessor definitions");
|
||||
|
||||
return new Tuple<List<string>, List<string>>(includeDirectories, preprocessorDefinitions);
|
||||
}
|
||||
|
||||
static private VCConfiguration GetProjectConfiguration(VCProject project, string configurationName, string platformName)
|
||||
{
|
||||
Logging.Logging.LogInfo("Attempting to retreive project configuration");
|
||||
|
||||
if (project == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IEnumerable configurations = project.Configurations as IEnumerable;
|
||||
foreach (Object configuration in configurations)
|
||||
{
|
||||
VCConfiguration vcProjectConfig = configuration as VCConfiguration;
|
||||
|
||||
if (vcProjectConfig != null &&
|
||||
vcProjectConfig.ConfigurationName == configurationName &&
|
||||
vcProjectConfig.Platform.Name == platformName)
|
||||
{
|
||||
return vcProjectConfig;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Logging.LogError("Failed to find project config matching with \"" + configurationName + "\"");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static private CommandObject CreateCommandObject(EnvDTE.ProjectItem item, List<string> includeDirectories, List<string> preprocessorDefinitions, string vcStandard, string cStandard, string configurationName, string platformName)
|
||||
{
|
||||
string objectName = item.Name;
|
||||
|
||||
Logging.Logging.LogInfo("Starting to create Command Object from item '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(item.Name) + "'");
|
||||
|
||||
try
|
||||
{
|
||||
DTE dte = item.DTE;
|
||||
|
||||
if (dte == null)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to retreive DTE object. Abort creating command object.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
VCFile vcFile = item.Object as VCFile;
|
||||
string subType = vcFile.SubType;
|
||||
|
||||
VCProject project = vcFile.project;
|
||||
VCConfiguration vcConfig = GetProjectConfiguration(project, configurationName, platformName);
|
||||
|
||||
if (vcConfig == null)
|
||||
{
|
||||
Logging.Logging.LogError("Project Configuration is null.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
VCFileConfiguration fc = vcFile.GetFileConfigurationForProjectConfiguration(vcConfig);
|
||||
VCCLCompilerTool t = fc.Tool as VCCLCompilerTool;
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
Logging.Logging.LogInfo("Unable to retrieve build tool. Using extension white list to determine file type.");
|
||||
}
|
||||
|
||||
if (IsSourceFile(item, t))
|
||||
{
|
||||
CommandObject commandObject = new CommandObject();
|
||||
commandObject.File = item.Name;
|
||||
|
||||
// only write source files to cdb, headers are implicit
|
||||
// however, retreive header directory
|
||||
if (CheckIsHeader(item))
|
||||
{
|
||||
Properties props = item.Properties;
|
||||
foreach (Property prop in props)
|
||||
{
|
||||
string propName = prop.Name;
|
||||
string propValue = prop.Value as String;
|
||||
|
||||
if (propName == "FullPath")
|
||||
{
|
||||
int i = propValue.LastIndexOf('\\');
|
||||
|
||||
propValue = propValue.Substring(0, i);
|
||||
|
||||
_headerDirectories.Add(propValue);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
string additionalOptions = "";
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
additionalOptions = t.AdditionalOptions;
|
||||
CompileAsOptions compileAs = t.CompileAs; // VCCLCompilerToolShim
|
||||
|
||||
if (additionalOptions == "$(NOINHERIT)")
|
||||
{
|
||||
additionalOptions = "";
|
||||
}
|
||||
|
||||
// check wheter it's a .c file, we don't want that...
|
||||
// TODO: there is a property for comilation as .c or .cpp file (/TC and /TP), try to retrieve it
|
||||
string extension = item.Properties.Item("Extension").Value.ToString();
|
||||
if (compileAs == CompileAsOptions.compileAsC)
|
||||
{
|
||||
vcStandard = "-std=" + cStandard;
|
||||
}
|
||||
}
|
||||
|
||||
// if a language standard was defined in the additional options the 'vcStandard' string is not used
|
||||
if (additionalOptions.Contains("-std="))
|
||||
{
|
||||
vcStandard = "";
|
||||
}
|
||||
|
||||
string directory = item.Properties.Item("FullPath").Value.ToString();
|
||||
|
||||
List<string> names = new List<string>();
|
||||
foreach (Property p in item.Properties)
|
||||
{
|
||||
names.Add(p.Name);
|
||||
}
|
||||
|
||||
int idx = directory.LastIndexOf('\\');
|
||||
if (idx != -1)
|
||||
{
|
||||
directory = directory.Substring(0, idx + 1);
|
||||
}
|
||||
|
||||
directory = directory.Replace('\\', '/');
|
||||
commandObject.File = directory + item.Name;
|
||||
|
||||
commandObject.Directory = System.IO.Path.GetDirectoryName(dte.Solution.FullName); // TODO: replace with actual cdb location
|
||||
commandObject.Directory = commandObject.Directory.Replace('\\', '/');
|
||||
|
||||
commandObject.Command = "clang-tool ";
|
||||
|
||||
foreach (string flag in _compatibilityFlags)
|
||||
{
|
||||
commandObject.Command += flag + " ";
|
||||
}
|
||||
|
||||
commandObject.Command += _compatibilityVersionFlag + " ";
|
||||
|
||||
foreach (string dir in includeDirectories)
|
||||
{
|
||||
commandObject.Command += " -isystem '" + dir + "' "; // using '-isystem' because it allows for use of quotes and pointy brackets in source files. In other words it's more robust. It's slower than '-I' though
|
||||
}
|
||||
|
||||
foreach (string prepDef in preprocessorDefinitions)
|
||||
{
|
||||
commandObject.Command += " -D " + prepDef + " ";
|
||||
}
|
||||
|
||||
foreach (string flag in _additionalCompileFlags)
|
||||
{
|
||||
commandObject.Command += " -D " + flag + " ";
|
||||
}
|
||||
|
||||
commandObject.Command += vcStandard + " ";
|
||||
|
||||
commandObject.Command += additionalOptions + " ";
|
||||
|
||||
commandObject.Command += "'" + commandObject.File + "'";
|
||||
|
||||
return commandObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogInfo("Item discarded, wrong code model");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
|
||||
Logging.Logging.LogError("Failed to create command object.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static private bool IsSourceFile(ProjectItem item, VCCLCompilerTool tool)
|
||||
{
|
||||
if (tool != null) // if the tool is null it's probably not a normal VC project, indicating that the file code model is unavailable
|
||||
{
|
||||
if (item.FileCodeModel != null && item.FileCodeModel.Language == CodeModelLanguageConstants.vsCMLanguageVC)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (_extensionWhiteList.Contains(GetFileExtension(item)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static private bool CheckIsHeader(EnvDTE.ProjectItem item)
|
||||
{
|
||||
Properties props = item.Properties;
|
||||
|
||||
string propString = "";
|
||||
|
||||
try
|
||||
{
|
||||
foreach (Property prop in props)
|
||||
{
|
||||
string propName = prop.Name;
|
||||
string propValue = prop.Value as String;
|
||||
|
||||
propString += propName + " - " + propValue + "; ";
|
||||
|
||||
if (propName == "ItemType")
|
||||
{
|
||||
if (propValue as String == "ClInclude")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static private string ResolveVSMacro(VCConfiguration vcProjectConfig, string path)
|
||||
{
|
||||
string result = path;
|
||||
|
||||
try
|
||||
{
|
||||
Tuple<int, int> potentialMacroPosition = Utility.StringUtility.FindFirstRange(path, "$(", ")");
|
||||
|
||||
if (potentialMacroPosition != null)
|
||||
{
|
||||
string potentialMacro = path.Substring(potentialMacroPosition.Item1, potentialMacroPosition.Item2 - potentialMacroPosition.Item1 + 1);
|
||||
|
||||
string resolvedMacro = vcProjectConfig.Evaluate(potentialMacro);
|
||||
|
||||
result = path.Substring(0, potentialMacroPosition.Item1) + resolvedMacro + path.Substring(potentialMacroPosition.Item2 + 1);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static private void ReloadAll(DTE dte)
|
||||
{
|
||||
if (dte == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnvDTE.Solution solution = dte.Solution;
|
||||
|
||||
List<EnvDTE.Project> projects = Utility.SolutionUtility.GetSolutionProjectList(dte);
|
||||
|
||||
foreach (EnvDTE.Project project in projects)
|
||||
{
|
||||
_reloadedProjectGuids.Add(Utility.ProjectUtility.ReloadProject(project));
|
||||
}
|
||||
}
|
||||
|
||||
static private void UnloadReloadedProjects(DTE dte)
|
||||
{
|
||||
foreach (Guid guid in _reloadedProjectGuids)
|
||||
{
|
||||
Utility.ProjectUtility.UnloadProject(guid, dte);
|
||||
}
|
||||
}
|
||||
|
||||
static private void SetCompatibilityVersionFlag(VCProject project, string configurationName, string platformName)
|
||||
{
|
||||
Logging.Logging.LogInfo("Determining CL.exe (C++ compiler) version");
|
||||
|
||||
VCConfiguration vcProjectConfig = GetProjectConfiguration(project, configurationName, platformName);
|
||||
|
||||
if (vcProjectConfig != null)
|
||||
{
|
||||
IEnumerable projectTools = vcProjectConfig.Tools as IEnumerable;
|
||||
foreach (Object tool in projectTools)
|
||||
{
|
||||
try
|
||||
{
|
||||
VCCLCompilerTool compilerTool = tool as VCCLCompilerTool;
|
||||
|
||||
if (compilerTool != null)
|
||||
{
|
||||
int majorCompilerVersion = GetCLMajorVersion(compilerTool, vcProjectConfig);
|
||||
|
||||
if (majorCompilerVersion > -1)
|
||||
{
|
||||
Logging.Logging.LogInfo("Found compiler version " + majorCompilerVersion.ToString());
|
||||
|
||||
_compatibilityVersionFlag = _compatibilityVersionFlagBase + majorCompilerVersion.ToString();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogWarning("Failed to retreive VC Project Configuration. Using default compiler version");
|
||||
}
|
||||
}
|
||||
|
||||
static private int GetCLMajorVersion(VCCLCompilerTool compilerTool, VCConfiguration vcProjectConfig)
|
||||
{
|
||||
Logging.Logging.LogInfo("Looking up CL.exe (C++ compiler)");
|
||||
|
||||
if (compilerTool == null || vcProjectConfig == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
VCPlatform platform = vcProjectConfig.Platform as VCPlatform;
|
||||
string executableDirectories = platform.ExecutableDirectories;
|
||||
string[] seperatedDirectories = executableDirectories.Split(';');
|
||||
|
||||
List<string> finalDirectories = new List<string>();
|
||||
foreach (string directory in seperatedDirectories)
|
||||
{
|
||||
string resolvedDirectory = ResolveVSMacro(vcProjectConfig, directory);
|
||||
string[] splitResolvedDirectory = resolvedDirectory.Split(';'); // resolved macros might result in concatenated paths
|
||||
|
||||
foreach (string d in splitResolvedDirectory)
|
||||
{
|
||||
finalDirectories.Add(d);
|
||||
}
|
||||
}
|
||||
|
||||
string toolPath = compilerTool.ToolPath;
|
||||
|
||||
Logging.Logging.LogInfo("Found " + finalDirectories.Count.ToString() + " possible compiler directories.");
|
||||
|
||||
foreach (string fd in finalDirectories)
|
||||
{
|
||||
string path = fd + "\\" + toolPath;
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
FileVersionInfo info = FileVersionInfo.GetVersionInfo(path);
|
||||
int version = info.FileMajorPart;
|
||||
|
||||
Logging.Logging.LogInfo("Found compiler location. Compiler tool version is " + version.ToString());
|
||||
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
|
||||
Logging.Logging.LogWarning("Failed to find C++ compiler tool.");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// AFAIK there is no way to programmatically get the c++ standard version supported by any given VS version
|
||||
// instead I'm refearing to the VS docu for that information
|
||||
// https://msdn.microsoft.com/en-us/library/hh567368.aspx
|
||||
static private string GetCppStandardString(VCConfiguration vcProjectConfig)
|
||||
{
|
||||
if (vcProjectConfig == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string result = "";
|
||||
|
||||
IVCRulePropertyStorage rules = null;
|
||||
|
||||
try
|
||||
{
|
||||
rules = vcProjectConfig.Rules.Item("ConfigurationGeneral");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (rules != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string toolset = rules.GetUnevaluatedPropertyValue("PlatformToolset");
|
||||
|
||||
string justNumbers = new String(toolset.Where(Char.IsDigit).ToArray());
|
||||
|
||||
int versionNumber = int.Parse(justNumbers);
|
||||
|
||||
if (versionNumber < 120) // version 11 (2012)
|
||||
{
|
||||
result = "-std=c++11";
|
||||
}
|
||||
else if (versionNumber < 130) // version 12 (2013)
|
||||
{
|
||||
result = "-std=c++14";
|
||||
}
|
||||
else if (versionNumber < 150) // version 14 (2015)
|
||||
{
|
||||
result = "-std=c++14";
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static private string GetFileExtension(ProjectItem item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string name = item.Name;
|
||||
|
||||
int idx = name.LastIndexOf(".");
|
||||
|
||||
if (idx > -1 && idx < name.Length - 1)
|
||||
{
|
||||
return name.Substring(idx + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>4.0</OldToolsVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A585A530-E120-4C74-934E-D57ED12A7DA9}</ProjectGuid>
|
||||
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CoatiSoftware.SourcetrailPlugin</RootNamespace>
|
||||
<AssemblyName>sourcetrail_plugin_vs</AssemblyName>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.VisualStudio.OLE.Interop" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0">
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TemplateWizardInterface, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.11.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.11.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.VCProjectEngine, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Design" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<COMReference Include="EnvDTE">
|
||||
<Guid>{80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}</Guid>
|
||||
<VersionMajor>8</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="EnvDTE100">
|
||||
<Guid>{26AD1324-4B7C-44BC-84F8-B86AED45729F}</Guid>
|
||||
<VersionMajor>10</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="EnvDTE80">
|
||||
<Guid>{1A31287A-4D7D-413E-8E32-3B374931BD89}</Guid>
|
||||
<VersionMajor>8</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="EnvDTE90">
|
||||
<Guid>{2CE2370E-D744-4936-A090-3FFFE667B0E1}</Guid>
|
||||
<VersionMajor>9</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="Microsoft.VisualStudio.CommandBars">
|
||||
<Guid>{1CBA492E-7263-47BB-87FE-639000619B15}</Guid>
|
||||
<VersionMajor>8</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="stdole">
|
||||
<Guid>{00020430-0000-0000-C000-000000000046}</Guid>
|
||||
<VersionMajor>2</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Logging\FileLogger.cs" />
|
||||
<Compile Include="Logging\ILogger.cs" />
|
||||
<Compile Include="Logging\Logging.cs" />
|
||||
<Compile Include="Logging\LogManager.cs" />
|
||||
<Compile Include="Logging\LogMessage.cs" />
|
||||
<Compile Include="Logging\Obfuscation\NameObfuscator.cs" />
|
||||
<Compile Include="Logging\VSOutputLogger.cs" />
|
||||
<Compile Include="Multitasking\LimitedThreadsTaskScheduler.cs" />
|
||||
<Compile Include="Utility\CompilationDatabaseList.cs" />
|
||||
<Compile Include="Utility\DataUtility.cs" />
|
||||
<Compile Include="Utility\FileUtility.cs" />
|
||||
<Compile Include="Guids.cs" />
|
||||
<Compile Include="Utility\NetworkProtocolUtility.cs" />
|
||||
<Compile Include="Utility\NetworkUtility.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="GlobalSuppressions.cs" />
|
||||
<Compile Include="SourcetrailPluginPackage.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PkgCmdID.cs" />
|
||||
<Compile Include="SolutionParser\CommandObject.cs" />
|
||||
<Compile Include="SolutionParser\CompilationDatabase.cs" />
|
||||
<Compile Include="SolutionParser\SolutionParser.cs" />
|
||||
<Compile Include="Utility\ProjectUtility.cs" />
|
||||
<Compile Include="Utility\QueuedFileWriter.cs" />
|
||||
<Compile Include="Utility\SolutionUtility.cs" />
|
||||
<Compile Include="Utility\SystemUtility.cs" />
|
||||
<Compile Include="Utility\StringUtility.cs" />
|
||||
<Compile Include="Wizard\WindowCDBReady.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Wizard\WindowCDBReady.Designer.cs">
|
||||
<DependentUpon>WindowCDBReady.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Wizard\WindowCreateCDB.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Wizard\WindowCreateCDB.Designer.cs">
|
||||
<DependentUpon>WindowCreateCDB.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Wizard\ProjectSetupWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Wizard\ProjectSetupWindow.Designer.cs">
|
||||
<DependentUpon>ProjectSetupWindow.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Wizard\WindowMessage.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Wizard\WindowMessage.Designer.cs">
|
||||
<DependentUpon>WindowMessage.cs</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="VSPackage.resx">
|
||||
<MergeWithCTO>true</MergeWithCTO>
|
||||
<ManifestResourceName>VSPackage</ManifestResourceName>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Wizard\WindowCDBReady.resx">
|
||||
<DependentUpon>WindowCDBReady.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Wizard\WindowCreateCDB.resx">
|
||||
<DependentUpon>WindowCreateCDB.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Wizard\ProjectSetupWindow.resx">
|
||||
<DependentUpon>ProjectSetupWindow.cs</DependentUpon>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>ProjectSetupWindow1.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Wizard\WindowMessage.resx">
|
||||
<DependentUpon>WindowMessage.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="source.extension.vsixmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Key.snk" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<VSCTCompile Include="SourcetrailPlugin.vsct">
|
||||
<ResourceName>Menus.ctmenu</ResourceName>
|
||||
<SubType>Designer</SubType>
|
||||
</VSCTCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\favicon_16x16.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="sourcetrail.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup>
|
||||
<UseCodebase>true</UseCodebase>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>C:\Program Files %28x86%29\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe</StartProgram>
|
||||
<StartArguments>/rootsuffix Exp</StartArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>C:\Program Files %28x86%29\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe</StartProgram>
|
||||
<StartArguments>/rootsuffix Exp</StartArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!-- This is the file that defines the actual layout and type of the commands.
|
||||
It is divided in different sections (e.g. command definition, command
|
||||
placement, ...), with each defining a specific set of properties.
|
||||
See the comment before each section for more details about how to
|
||||
use it. -->
|
||||
|
||||
<!-- The VSCT compiler (the tool that translates this file into the binary
|
||||
format that VisualStudio will consume) has the ability to run a preprocessor
|
||||
on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
|
||||
it is possible to define includes and macros with the same syntax used
|
||||
in C++ files. Using this ability of the compiler here, we include some files
|
||||
defining some of the constants that we will use inside the file. -->
|
||||
|
||||
<!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
|
||||
<Extern href="stdidcmd.h"/>
|
||||
|
||||
<!--This header contains the command ids for the menus provided by the shell. -->
|
||||
<Extern href="vsshlids.h"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--The Commands section is where we the commands, menus and menu groups are defined.
|
||||
This section uses a Guid to identify the package that provides the command defined inside it. -->
|
||||
<Commands package="guidSourcetrailPluginPkg">
|
||||
<Bitmaps>
|
||||
<Bitmap guid="icon" href="Resources\favicon_16x16.png" usedList="icon0"/>
|
||||
</Bitmaps>
|
||||
|
||||
<Groups>
|
||||
|
||||
<Group guid="guidSourcetrailPluginCmdSet" id="ContextMenuGroup" priority="0x0600">
|
||||
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN"/>
|
||||
</Group>
|
||||
|
||||
<Group guid="guidSourcetrailPluginCmdSet" id="TopLevelMenu" priority="0x0600">
|
||||
<Parent guid="guidSHLMainMenu" id="IDM_VS_TOOL_MAINMENU"/>
|
||||
</Group>
|
||||
|
||||
<Group guid="guidSourcetrailPluginCmdSet" id="SubMenu" priority="0x0600">
|
||||
<Parent guid="guidSourcetrailPluginCmdSet" id="TopLevelMenu"/>
|
||||
</Group>
|
||||
|
||||
<!--
|
||||
<Group guid="guidSourcetrailPluginCmdSet" id="HelpMenu" priority="0x0600">
|
||||
<Parent guid="guidSourcetrailPluginCmdSet" id="TopLevelMenu"/>
|
||||
</Group>
|
||||
-->
|
||||
|
||||
</Groups>
|
||||
|
||||
<Buttons>
|
||||
|
||||
<Button guid="guidSourcetrailPluginCmdSet" id="cmdidSourcetrailSetActiveToken" priority="0x0100" type="Button">
|
||||
<Parent guid="guidSourcetrailPluginCmdSet" id="ContextMenuGroup" />
|
||||
<Icon guid="icon" id="icon0" />
|
||||
<Strings>
|
||||
<ButtonText>Set active Token</ButtonText>
|
||||
</Strings>
|
||||
</Button>
|
||||
|
||||
<Button guid="guidSourcetrailPluginCmdSet" id="cmdidSourcetrailCreateCDB" priority="0x0100" type="Button">
|
||||
<Parent guid="guidSourcetrailPluginCmdSet" id="SubMenu" />
|
||||
<Icon guid="icon" id="icon0" />
|
||||
<Strings>
|
||||
<ButtonText>Create CDB</ButtonText>
|
||||
</Strings>
|
||||
</Button>
|
||||
|
||||
<Button guid="guidSourcetrailPluginCmdSet" id="cmdidSourcetrailOpenLogFolder" priority="0x0100" type="Button">
|
||||
<Parent guid="guidSourcetrailPluginCmdSet" id="SubMenu" />
|
||||
<Strings>
|
||||
<ButtonText>Open Log Directory</ButtonText>
|
||||
</Strings>
|
||||
</Button>
|
||||
|
||||
<!--
|
||||
<Button guid="guidSourcetrailPluginCmdSet" id="cmdidSourcetrailHelp" priority="0x0100" type="Button">
|
||||
<Parent guid="guidSourcetrailPluginCmdSet" id="HelpMenu" />
|
||||
<Strings>
|
||||
<ButtonText>Online Help</ButtonText>
|
||||
</Strings>
|
||||
</Button>
|
||||
-->
|
||||
|
||||
</Buttons>
|
||||
|
||||
<Menus>
|
||||
|
||||
<Menu guid="guidSourcetrailPluginCmdSet" id="TopLevelMenu" priority="0x700" type="Menu">
|
||||
<Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS"/>
|
||||
<Strings>
|
||||
<ButtonText>Sourcetrail</ButtonText>
|
||||
<CommandName>Sourcetrail</CommandName>
|
||||
</Strings>
|
||||
</Menu>
|
||||
|
||||
<!--
|
||||
<Menu guid="guidSourcetrailPluginCmdSet" id="HelpMenu" priority="0x700" type="Menu">
|
||||
<Parent guid="guidSourcetrailPluginCmdSet" id="TopLevelMenu"/>
|
||||
<Strings>
|
||||
<ButtonText>Sourcetrail Help</ButtonText>
|
||||
<CommandName>Sourcetrail Help</CommandName>
|
||||
</Strings>
|
||||
</Menu>
|
||||
-->
|
||||
|
||||
</Menus>
|
||||
|
||||
</Commands>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Symbols>
|
||||
<!-- This is the package guid. -->
|
||||
<GuidSymbol name="guidSourcetrailPluginPkg" value="{acf15780-03b5-440e-a41e-db79b7043fc2}" />
|
||||
|
||||
<!-- This is the guid used to group the menu commands together -->
|
||||
<GuidSymbol name="guidSourcetrailPluginCmdSet" value="{0efb005b-715c-4a62-8a9b-1e5a870e6c34}">
|
||||
|
||||
<IDSymbol name="ContextMenuGroup" value="0x1020" />
|
||||
<IDSymbol name="cmdidSourcetrailPing" value="0x0100" />
|
||||
<IDSymbol name="cmdidSourcetrailFile" value="0x0101"/>
|
||||
<IDSymbol name="cmdidSourcetrailGetActiveFileName" value="0x0102"/>
|
||||
<IDSymbol name="cmdidSourcetrailGetActiveLineNumber" value="0x0103"/>
|
||||
<IDSymbol name="cmdidSourcetrailSetActiveToken" value="0x0104"/>
|
||||
<IDSymbol name="cmdidSourcetrailCreateProject" value="0x0105"/>
|
||||
<IDSymbol name="cmdidSourcetrailCreateCDB" value="0x0106"/>
|
||||
<IDSymbol name="cmdidSourcetrailOpenLogFolder" value="0x0107"/>
|
||||
<IDSymbol name="TopLevelMenu" value="0x1021"/>
|
||||
<IDSymbol name="SubMenu" value="0x1022"/>
|
||||
<IDSymbol name="HelpMenu" value="0x1023"/>
|
||||
<IDSymbol name="cmdidSourcetrailHelp" value="0x1024"/>
|
||||
</GuidSymbol>
|
||||
|
||||
|
||||
|
||||
<GuidSymbol name="guidImages" value="{e447cfde-511d-4f75-80c1-a40b8a03152a}" >
|
||||
<IDSymbol name="bmpPic1" value="1" />
|
||||
<IDSymbol name="bmpPic2" value="2" />
|
||||
<IDSymbol name="bmpPicSearch" value="3" />
|
||||
<IDSymbol name="bmpPicX" value="4" />
|
||||
<IDSymbol name="bmpPicArrows" value="5" />
|
||||
<IDSymbol name="bmpPicStrikethrough" value="6" />
|
||||
</GuidSymbol>
|
||||
|
||||
<GuidSymbol name="icon" value="{403BFDD2-B84C-4BCE-A1D1-B16F9F2B8230}" >
|
||||
<IDSymbol name="icon0" value="1" />
|
||||
</GuidSymbol>
|
||||
|
||||
</Symbols>
|
||||
|
||||
</CommandTable>
|
||||
+590
@@ -0,0 +1,590 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using EnvDTE;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin
|
||||
{
|
||||
public class OptionPageGrid : DialogPage
|
||||
{
|
||||
private uint _serverPort = 6666;
|
||||
private uint _clientPort = 6667;
|
||||
private bool _logging = false;
|
||||
private bool _obfuscateLogging = false;
|
||||
private uint _threadCount = 1;
|
||||
|
||||
public delegate void Callback();
|
||||
public static Callback _serverPortChangeCallback = null;
|
||||
public static Callback _clientPortChangeCallback = null;
|
||||
public static Callback _loggingToggled = null;
|
||||
public static Callback _obfuscationToggled = null;
|
||||
public static Callback _threadCountChanged = null;
|
||||
|
||||
[Category("Sourcetrail")]
|
||||
[DisplayName("VS Port")]
|
||||
[Description("The port on which Visual Studio will receive messages")]
|
||||
public uint ServerPort
|
||||
{
|
||||
get { return _serverPort; }
|
||||
set
|
||||
{
|
||||
_serverPort = value;
|
||||
if (_serverPortChangeCallback != null)
|
||||
{
|
||||
_serverPortChangeCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Sourcetrail")]
|
||||
[DisplayName("Sourcetrail Port")]
|
||||
[Description("The port on which Sourcetrail will receive messages")]
|
||||
public uint ClientPort
|
||||
{
|
||||
get { return _clientPort; }
|
||||
set
|
||||
{
|
||||
_clientPort = value;
|
||||
if (_clientPortChangeCallback != null)
|
||||
{
|
||||
_clientPortChangeCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Sourcetrail")]
|
||||
[DisplayName("File Logging")]
|
||||
[Description("Enables or disables file logging for the plugin")]
|
||||
public bool LoggingEnabled
|
||||
{
|
||||
get { return _logging; }
|
||||
set
|
||||
{
|
||||
_logging = value;
|
||||
if(_loggingToggled != null)
|
||||
{
|
||||
_loggingToggled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Sourcetrail")]
|
||||
[DisplayName("Log Obfuscation")]
|
||||
[Description("Names will be obfuscated in log files. Note that already logged data will not be obfuscated retroactively. A dictionary file will be created that you can use to make sense of obfuscated logs. Keep this dictionary to yourself!")]
|
||||
public bool ObfuscateLogging
|
||||
{
|
||||
get { return _obfuscateLogging; }
|
||||
set
|
||||
{
|
||||
_obfuscateLogging = value;
|
||||
if (_obfuscationToggled != null)
|
||||
{
|
||||
_obfuscationToggled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Sourcetrail")]
|
||||
[DisplayName("Thread Count")]
|
||||
[Description("The maximum number of threads that will be used while building Compilation Databases")]
|
||||
public uint ThreadCount
|
||||
{
|
||||
get { return _threadCount; }
|
||||
set
|
||||
{
|
||||
_threadCount = value;
|
||||
if(_threadCountChanged != null)
|
||||
{
|
||||
_threadCountChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OptionPageGrid()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[PackageRegistration(UseManagedResourcesOnly = true)]
|
||||
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
|
||||
[ProvideMenuResource("Menus.ctmenu", 1)]
|
||||
[Guid(GuidList.guidSourcetrailPluginPkgString)]
|
||||
[ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.NoSolution)]
|
||||
[ProvideOptionPage(typeof(OptionPageGrid), "Sourcetrail", "Sourcetrail Settings", 0, 0, true)]
|
||||
|
||||
public sealed class SourcetrailPluginPackage : Package
|
||||
{
|
||||
private MenuCommand _menuItemSetActiveToken = null;
|
||||
private MenuCommand _menuItemCreateProject = null;
|
||||
private MenuCommand _menuItemCreateCDB = null;
|
||||
private MenuCommand _menuItemOpenLogDir = null;
|
||||
|
||||
private SolutionEvents _solutionEvents = null;
|
||||
|
||||
private bool _validSolutionLoaded = false;
|
||||
|
||||
Utility.CompilationDatabaseList _cdbList = new Utility.CompilationDatabaseList();
|
||||
|
||||
public uint ServerPort
|
||||
{
|
||||
get
|
||||
{
|
||||
OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
|
||||
return page.ServerPort;
|
||||
}
|
||||
}
|
||||
|
||||
public uint ClientPort
|
||||
{
|
||||
get
|
||||
{
|
||||
OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
|
||||
return page.ClientPort;
|
||||
}
|
||||
}
|
||||
|
||||
public bool LoggingEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
|
||||
return page.LoggingEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
public bool LogObfuscationEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
|
||||
return page.ObfuscateLogging;
|
||||
}
|
||||
}
|
||||
|
||||
public uint ThreadCount
|
||||
{
|
||||
get
|
||||
{
|
||||
OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
|
||||
return page.ThreadCount;
|
||||
}
|
||||
}
|
||||
|
||||
System.Threading.Thread _serverThread = null;
|
||||
|
||||
|
||||
|
||||
public SourcetrailPluginPackage()
|
||||
{}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
InitLogging();
|
||||
InitNetwork();
|
||||
|
||||
Utility.FileUtility._errorCallback = new Utility.FileUtility.ErrorCallback(OnFileUtilityError);
|
||||
|
||||
// register callbacks for changes of plugin settings
|
||||
OptionPageGrid._serverPortChangeCallback = new OptionPageGrid.Callback(OnServerPortChanged);
|
||||
OptionPageGrid._clientPortChangeCallback = new OptionPageGrid.Callback(OnClientPortChanged);
|
||||
OptionPageGrid._loggingToggled = new OptionPageGrid.Callback(OnLoggingToggled);
|
||||
OptionPageGrid._obfuscationToggled = new OptionPageGrid.Callback(OnObfuscationToggled);
|
||||
|
||||
// register the plugin UI elements
|
||||
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
|
||||
if ( null != mcs )
|
||||
{
|
||||
CommandID setActiveTokenCommandID = new CommandID(GuidList.guidSourcetrailPluginCmdSet, (int)PkgCmdIDList.cmdidSourcetrailSetActiveToken);
|
||||
CommandID createProjectID = new CommandID(GuidList.guidSourcetrailPluginCmdSet, (int)PkgCmdIDList.cmdidSourcetrailCreateProject);
|
||||
CommandID createCDBID = new CommandID(GuidList.guidSourcetrailPluginCmdSet, (int)PkgCmdIDList.cmdidSourcetrailCreateCDB);
|
||||
CommandID openLogDirID = new CommandID(GuidList.guidSourcetrailPluginCmdSet, (int)PkgCmdIDList.cmdidSourcetrailOpenLogFolder);
|
||||
|
||||
_menuItemSetActiveToken = new MenuCommand(MenuItemCallback, setActiveTokenCommandID);
|
||||
_menuItemCreateProject = new MenuCommand(MenuItemCallback, createProjectID);
|
||||
_menuItemCreateCDB = new MenuCommand(MenuItemCallback, createCDBID);
|
||||
_menuItemOpenLogDir = new MenuCommand(MenuItemCallback, openLogDirID);
|
||||
|
||||
_menuItemCreateProject.Enabled = false;
|
||||
_menuItemSetActiveToken.Enabled = false;
|
||||
_menuItemCreateCDB.Enabled = false;
|
||||
_menuItemOpenLogDir.Enabled = true;
|
||||
|
||||
mcs.AddCommand(_menuItemSetActiveToken);
|
||||
mcs.AddCommand(_menuItemCreateProject);
|
||||
mcs.AddCommand(_menuItemCreateCDB);
|
||||
mcs.AddCommand(_menuItemOpenLogDir);
|
||||
}
|
||||
|
||||
// register callbacks to enable/disable interaction for eligible solutions
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
_solutionEvents = dte.Events.SolutionEvents;
|
||||
|
||||
_solutionEvents.Opened += OnSolutionOpened;
|
||||
_solutionEvents.AfterClosing += OnSolutionClosed;
|
||||
|
||||
SendPing();
|
||||
|
||||
Logging.Logging.LogInfo("Initialization done");
|
||||
}
|
||||
|
||||
void OnSolutionOpened()
|
||||
{
|
||||
Logging.Logging.LogInfo("A solution was loaded, checking languages");
|
||||
|
||||
try
|
||||
{
|
||||
// the sourcetrail ui should only be enabled when the solution contains C/C++ projects
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
List<String> languages = Utility.SolutionUtility.GetSolutionLanguages(dte);
|
||||
|
||||
string solutionPath = Utility.SolutionUtility.GetSolutionPath(dte);
|
||||
|
||||
if(_cdbList.CheckCDBForSolutionExists(solutionPath))
|
||||
{
|
||||
Logging.Logging.LogInfo("A CDB for the loaded solution already exists.");
|
||||
}
|
||||
|
||||
bool enable = false;
|
||||
foreach (String language in languages)
|
||||
{
|
||||
if (language == CodeModelLanguageConstants.vsCMLanguageVC
|
||||
|| language == CodeModelLanguageConstants.vsCMLanguageMC)
|
||||
{
|
||||
Logging.Logging.LogInfo("C/C++ project was detected");
|
||||
enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (enable)
|
||||
{
|
||||
Logging.Logging.LogInfo("Enabling plugin UI");
|
||||
_menuItemSetActiveToken.Enabled = true;
|
||||
_menuItemCreateProject.Enabled = true;
|
||||
_menuItemCreateCDB.Enabled = true;
|
||||
|
||||
_validSolutionLoaded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_validSolutionLoaded = false;
|
||||
|
||||
Logging.Logging.LogInfo("No C/C++ project was detected");
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
DisplayMessage("Error", e.Message);
|
||||
Logging.Logging.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
void OnSolutionClosed()
|
||||
{
|
||||
Logging.Logging.LogInfo("Solution closed, disabling plugin UI");
|
||||
|
||||
_menuItemSetActiveToken.Enabled = false;
|
||||
_menuItemCreateProject.Enabled = false;
|
||||
_menuItemCreateCDB.Enabled = false;
|
||||
|
||||
_validSolutionLoaded = false;
|
||||
}
|
||||
|
||||
private void InitNetwork()
|
||||
{
|
||||
Logging.Logging.LogInfo("Initializing Network with Server Port " + ServerPort.ToString() + " and Client Port " + ClientPort.ToString());
|
||||
|
||||
Utility.AsynchronousSocketListener._port = ServerPort;
|
||||
Utility.AsynchronousSocketListener server = new Utility.AsynchronousSocketListener();
|
||||
Utility.AsynchronousSocketListener._onReadCallback = new Utility.AsynchronousSocketListener.OnReadCallback(OnNetworkReadCallback);
|
||||
Utility.AsynchronousSocketListener._onErrorCallback = new Utility.AsynchronousSocketListener.OnReadCallback(OnNetworkErrorCallback);
|
||||
_serverThread = new System.Threading.Thread(server.DoWork);
|
||||
_serverThread.Start();
|
||||
|
||||
Utility.AsynchronousClient._port = ClientPort;
|
||||
Utility.AsynchronousClient._onErrorCallback = new Utility.AsynchronousSocketListener.OnReadCallback(OnNetworkErrorCallback);
|
||||
}
|
||||
|
||||
private void InitLogging()
|
||||
{
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
|
||||
Logging.FileLogger fileLogger = new Logging.FileLogger();
|
||||
Logging.VSOutputLogger vsLogger = new Logging.VSOutputLogger(dte);
|
||||
|
||||
Logging.LogManager.GetInstance().Loggers.Add(fileLogger);
|
||||
Logging.LogManager.GetInstance().Loggers.Add(vsLogger);
|
||||
Logging.LogManager.GetInstance().LoggingEnabled = LoggingEnabled;
|
||||
|
||||
Logging.Obfuscation.NameObfuscator.Enabled(LogObfuscationEnabled);
|
||||
|
||||
Logging.Logging.LogInfo("Logging initialized");
|
||||
}
|
||||
|
||||
private void SendPing()
|
||||
{
|
||||
string message = Utility.NetworkProtocolUtility.CreatePingMessage();
|
||||
|
||||
Utility.AsynchronousClient.Send(message);
|
||||
}
|
||||
|
||||
private void OnCreateProject(List<EnvDTE.Project> projects, string configurationName, string platformName, string targetDir, string fileName, string cStandard)
|
||||
{
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
|
||||
Wizard.WindowCreateCDB createCDB = new Wizard.WindowCreateCDB();
|
||||
createCDB.Projects = projects;
|
||||
createCDB.ConfigurationName = configurationName;
|
||||
createCDB.PlatformName = platformName;
|
||||
createCDB.TargetDir = targetDir;
|
||||
createCDB.FileName = fileName;
|
||||
createCDB.CStandard = cStandard;
|
||||
createCDB.ThreadCount = (int)ThreadCount;
|
||||
createCDB.SolutionDir = Utility.SolutionUtility.GetSolutionPath(dte);
|
||||
|
||||
createCDB.CDB = _cdbList.GetCDBForSolution(createCDB.SolutionDir, targetDir + "\\" + fileName + ".json");
|
||||
|
||||
createCDB.CallbackOnFinishedCreatingCDB = HandleFinishedCDB;
|
||||
|
||||
createCDB.StartWorking();
|
||||
createCDB.ShowDialog();
|
||||
}
|
||||
|
||||
private void HandleFinishedCDB(Wizard.WindowCreateCDB.CreationResult creationResult)
|
||||
{
|
||||
if(creationResult._cdb != null && creationResult._cdbDirectory.Length > 0 && creationResult._cdbName.Length > 0)
|
||||
{
|
||||
_cdbList.AppendOrUpdate(creationResult._cdb);
|
||||
_cdbList.SaveMetaData();
|
||||
|
||||
Wizard.WindowCDBReady dialog = new Wizard.WindowCDBReady();
|
||||
dialog.setData(creationResult);
|
||||
dialog.ShowDialog();
|
||||
|
||||
_cdbList.Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogError("Invalid data received");
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuItemCallback(object sender, EventArgs e)
|
||||
{
|
||||
MenuCommand menuCommand = sender as MenuCommand;
|
||||
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
|
||||
if (menuCommand != null)
|
||||
{
|
||||
if (menuCommand.CommandID.ID == (int)PkgCmdIDList.cmdidSourcetrailSetActiveToken)
|
||||
{
|
||||
string fileName = Utility.FileUtility.GetActiveDocumentName(dte);
|
||||
string filePath = Utility.FileUtility.GetActiveDocumentPath(dte);
|
||||
|
||||
int lineNumber = Utility.FileUtility.GetActiveLineNumber(dte);
|
||||
int columnNumber = Utility.FileUtility.GetActiveColumnNumber(dte);
|
||||
|
||||
string message = Utility.NetworkProtocolUtility.CreateActivateTokenMessage(filePath + fileName, lineNumber, columnNumber);
|
||||
|
||||
Utility.AsynchronousClient.Send(message);
|
||||
}
|
||||
else if(menuCommand.CommandID.ID == (int)PkgCmdIDList.cmdidSourcetrailCreateCDB)
|
||||
{
|
||||
CreateCompilationDatabase(dte);
|
||||
}
|
||||
else if(menuCommand.CommandID.ID == (int)PkgCmdIDList.cmdidSourcetrailCreateProject)
|
||||
{
|
||||
// show hint to use CDB methad (only for CDB beta) and create project on ok
|
||||
Wizard.WindowMessage windowMessage = new Wizard.WindowMessage();
|
||||
windowMessage.Title = "Hint";
|
||||
windowMessage.Message = "Consider using 'Create CDB' if errors arise during Sourcetrail's indexing. This will become standard in the future.";
|
||||
windowMessage.OnOK = CreateSourcetrailProjectOld;
|
||||
windowMessage.RefreshWindow();
|
||||
windowMessage.ShowDialog();
|
||||
}
|
||||
else if(menuCommand.CommandID.ID == (int)PkgCmdIDList.cmdidSourcetrailOpenLogFolder)
|
||||
{
|
||||
Utility.SystemUtility.OpenWindowsExplorerAtDirectory(Utility.DataUtility.GetStandardFolderDirectory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// will be removed once the CDB project creation is fully integrated
|
||||
private void CreateSourcetrailProjectOld()
|
||||
{
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
|
||||
string solutionName = Utility.SolutionUtility.GetSolutionPath(dte);
|
||||
|
||||
if (solutionName == "") // TODO: make a better fallback for non-existant solution
|
||||
{
|
||||
List<string> items = Utility.SolutionUtility.GetSolutionProjectsFullNames(dte);
|
||||
|
||||
if (items.Count > 0)
|
||||
{
|
||||
solutionName = items[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (solutionName.Length > 0)
|
||||
{
|
||||
string message = Utility.NetworkProtocolUtility.CreateCreateProjectMessage(solutionName);
|
||||
|
||||
Utility.AsynchronousClient.Send(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayMessage("Sourcetrail", "Can not create a Sourcetrail Project. Please check whether your VS solution is a valid C or C++ solution and is saved.");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkReadCallback(string message)
|
||||
{
|
||||
Utility.NetworkProtocolUtility.MESSAGE_TYPE messageType = Utility.NetworkProtocolUtility.GetMessageType(message);
|
||||
|
||||
if(messageType == Utility.NetworkProtocolUtility.MESSAGE_TYPE.MOVE_CURSOR)
|
||||
{
|
||||
Utility.NetworkProtocolUtility.CursorPosition cursorPosition = Utility.NetworkProtocolUtility.ParseSetCursorMessage(message);
|
||||
if (cursorPosition.Valid)
|
||||
{
|
||||
cursorPosition.ColumnNumber += 1; // VS counts columns starting at 1, sourcetrail starts at 0
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
if (Utility.FileUtility.OpenSourceFile(dte, cursorPosition.FilePath))
|
||||
{
|
||||
Utility.FileUtility.GoToLine(dte, cursorPosition.LineNumber, cursorPosition.ColumnNumber);
|
||||
|
||||
Utility.SystemUtility.GetWindowFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(messageType == Utility.NetworkProtocolUtility.MESSAGE_TYPE.CREATE_CDB)
|
||||
{
|
||||
if(_validSolutionLoaded)
|
||||
{
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
|
||||
CreateCompilationDatabase(dte);
|
||||
}
|
||||
}
|
||||
else if(messageType == Utility.NetworkProtocolUtility.MESSAGE_TYPE.PING)
|
||||
{
|
||||
SendPing();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkErrorCallback(string message)
|
||||
{
|
||||
Logging.Logging.LogError("Network Error: " + message.ToString());
|
||||
DisplayMessage("Sourcetrail Network Error", message);
|
||||
}
|
||||
|
||||
private void OnFileUtilityError(string message)
|
||||
{
|
||||
Logging.Logging.LogError("File Error: " + message.ToString());
|
||||
DisplayMessage("Sourcetrail File Error", message);
|
||||
}
|
||||
|
||||
private void OnServerPortChanged()
|
||||
{
|
||||
Logging.Logging.LogInfo("Changing Server Port to " + ServerPort.ToString());
|
||||
|
||||
Utility.AsynchronousSocketListener._port = ServerPort;
|
||||
|
||||
_serverThread.Abort();
|
||||
Utility.AsynchronousSocketListener server = new Utility.AsynchronousSocketListener();
|
||||
_serverThread = new System.Threading.Thread(server.DoWork);
|
||||
_serverThread.Start();
|
||||
}
|
||||
|
||||
private void OnClientPortChanged()
|
||||
{
|
||||
Logging.Logging.LogInfo("Changing Client Port to " + ClientPort.ToString());
|
||||
|
||||
Utility.AsynchronousClient._port = ClientPort;
|
||||
}
|
||||
|
||||
private void OnLoggingToggled()
|
||||
{
|
||||
Logging.LogManager.GetInstance().LoggingEnabled = LoggingEnabled;
|
||||
|
||||
if(LoggingEnabled)
|
||||
{
|
||||
Logging.Logging.LogInfo("Logging enabled");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnObfuscationToggled()
|
||||
{
|
||||
Logging.Obfuscation.NameObfuscator.Enabled(LogObfuscationEnabled);
|
||||
|
||||
if(LogObfuscationEnabled)
|
||||
{
|
||||
Logging.Logging.LogInfo("Log Obfuscation enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogInfo("Log Obfuscation disabled");
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayMessage(string title, string message)
|
||||
{
|
||||
IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
|
||||
Guid clsid = Guid.Empty;
|
||||
int result;
|
||||
Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
|
||||
0,
|
||||
ref clsid,
|
||||
title,
|
||||
message,
|
||||
string.Empty,
|
||||
0,
|
||||
OLEMSGBUTTON.OLEMSGBUTTON_OK,
|
||||
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
|
||||
OLEMSGICON.OLEMSGICON_INFO,
|
||||
0, // false
|
||||
out result));
|
||||
}
|
||||
|
||||
private void CreateCompilationDatabase(DTE dte)
|
||||
{
|
||||
Logging.Logging.LogInfo("Preparing CDB dialog");
|
||||
|
||||
Wizard.ProjectSetupWindow window = new Wizard.ProjectSetupWindow();
|
||||
|
||||
Utility.SolutionUtility.SolutionStructure projectStructure = Utility.SolutionUtility.GetSolutionVCProjects(dte);
|
||||
List<List<string>> configsAndPlatforms = Utility.SolutionUtility.GetConfigurationAndPlatformNames(dte);
|
||||
|
||||
window._projectStructure = projectStructure;
|
||||
|
||||
window._configurations = configsAndPlatforms[0];
|
||||
window._platforms = configsAndPlatforms[1];
|
||||
|
||||
string directory = System.IO.Path.GetDirectoryName(dte.Solution.FullName);
|
||||
window._solutionDirectory = directory;
|
||||
|
||||
string solutionName = System.IO.Path.GetFileNameWithoutExtension(dte.Solution.FullName);
|
||||
window._solutionFileName = solutionName;
|
||||
|
||||
bool containsCFiles = true; // Utility.SolutionUtility.ContainsCFiles(dte); // takes ridiculously long, I'd rather just display the option by default
|
||||
window._containsCFiles = containsCFiles;
|
||||
|
||||
window._cdb = _cdbList.GetMostCurrentCDBForSolution(Utility.SolutionUtility.GetSolutionPath(dte));
|
||||
|
||||
window.UpdateGUI();
|
||||
window._onCreateProject = OnCreateProject;
|
||||
|
||||
window.ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
class CompilationDatabaseList
|
||||
{
|
||||
private List<SolutionParser.CompilationDatabase> _cdbs = new List<SolutionParser.CompilationDatabase>();
|
||||
|
||||
public List<SolutionParser.CompilationDatabase> CDBs
|
||||
{
|
||||
get { return _cdbs; }
|
||||
// set { _cdbs = value; }
|
||||
}
|
||||
|
||||
public CompilationDatabaseList()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void AppendOrUpdate(SolutionParser.CompilationDatabase cdb)
|
||||
{
|
||||
if(_cdbs.Exists(item => item.Name == cdb.Name && item.Directory == cdb.Directory) == false)
|
||||
{
|
||||
_cdbs.Add(cdb);
|
||||
}
|
||||
else
|
||||
{
|
||||
int idx = _cdbs.FindIndex(item => item.Name == cdb.Name && item.Directory == cdb.Directory);
|
||||
_cdbs[idx] = cdb;
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
List<SolutionParser.CompilationDatabase> cdbs = new List<SolutionParser.CompilationDatabase>();
|
||||
|
||||
try
|
||||
{
|
||||
string data = Utility.DataUtility.GetInstance().GetData();
|
||||
cdbs = SolutionParser.CompilationDatabase.ParseCDBsMetaData(data);
|
||||
|
||||
foreach (SolutionParser.CompilationDatabase cdb in cdbs)
|
||||
{
|
||||
cdb.CheckCDBExists();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to aquire data: " + e.Message);
|
||||
}
|
||||
|
||||
_cdbs = cdbs;
|
||||
}
|
||||
|
||||
public List<SolutionParser.CompilationDatabase> GetCDBsForSolution(string solutionPath)
|
||||
{
|
||||
return _cdbs.FindAll(item => item.SourceProject == solutionPath);
|
||||
}
|
||||
|
||||
public SolutionParser.CompilationDatabase GetCDBForSolution(string solutionPath)
|
||||
{
|
||||
return _cdbs.Find(item => item.SourceProject == solutionPath);
|
||||
}
|
||||
|
||||
public SolutionParser.CompilationDatabase GetMostCurrentCDBForSolution(string solutionPath)
|
||||
{
|
||||
SolutionParser.CompilationDatabase result = null;
|
||||
|
||||
try
|
||||
{
|
||||
List<SolutionParser.CompilationDatabase> candidates = GetCDBsForSolution(solutionPath);
|
||||
|
||||
System.DateTime youngest = System.DateTime.MinValue;
|
||||
foreach (SolutionParser.CompilationDatabase cdb in candidates)
|
||||
{
|
||||
if (cdb.LastUpdated >= youngest)
|
||||
{
|
||||
youngest = cdb.LastUpdated;
|
||||
result = cdb;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to find cdb: " + e.Message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public SolutionParser.CompilationDatabase GetCDBForSolution(string solutionPath, string cdbPath)
|
||||
{
|
||||
return _cdbs.Find(item => item.SourceProject == solutionPath && (item.Directory + "\\" + item.Name + ".json") == cdbPath);
|
||||
}
|
||||
|
||||
public bool CheckCDBForSolutionExists(string solutionPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
SolutionParser.CompilationDatabase cdb = GetCDBForSolution(solutionPath);
|
||||
if (cdb != null && System.IO.File.Exists(cdb.Directory + "\\" + cdb.Name + ".json"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to check cdb: " + e.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SaveMetaData()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
XmlNode root = doc.CreateElement("cdbs");
|
||||
|
||||
foreach (SolutionParser.CompilationDatabase cdb in _cdbs)
|
||||
{
|
||||
XmlNode metaData = cdb.GetMetaDataXML(doc);
|
||||
|
||||
root.AppendChild(metaData);
|
||||
}
|
||||
|
||||
System.IO.StringWriter writer = new System.IO.StringWriter();
|
||||
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(XmlElement));
|
||||
serializer.Serialize(writer, root);
|
||||
|
||||
DataUtility.GetInstance().ClearData();
|
||||
DataUtility.GetInstance().AppendData(writer.ToString());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to save meta data: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void UnloadCDBs()
|
||||
{
|
||||
if(_cdbs == null)
|
||||
{
|
||||
Logging.Logging.LogWarning("Member '_cdbs' is null, aborting.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(SolutionParser.CompilationDatabase cdb in _cdbs)
|
||||
{
|
||||
cdb.ClearCommandObjects();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
class DataUtility
|
||||
{
|
||||
static private string _standardFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Coati Software\\Plugins\\VS\\";
|
||||
static private string _standardFileName = "cdbs.sourcetraildata";
|
||||
|
||||
static private DataUtility _instance = null;
|
||||
|
||||
static private bool _valid = true; // stores if a file system operation failed, indicating that there is something wrong
|
||||
|
||||
static public string GetStandardFolderDirectory()
|
||||
{
|
||||
return _standardFolder;
|
||||
}
|
||||
|
||||
static bool Valid
|
||||
{
|
||||
get { return _valid; }
|
||||
}
|
||||
|
||||
static public DataUtility GetInstance()
|
||||
{
|
||||
if(_instance == null)
|
||||
{
|
||||
_instance = new DataUtility();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private DataUtility()
|
||||
{
|
||||
CreateStandardFolderIfNotExists();
|
||||
CreateStandardFileIfNotExists();
|
||||
}
|
||||
|
||||
public void AppendData(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (System.IO.StreamWriter file = System.IO.File.AppendText(_standardFolder + _standardFileName))
|
||||
{
|
||||
file.WriteLine(data);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to write data to file '" + _standardFolder + _standardFileName + "':" + e.Message);
|
||||
_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetData()
|
||||
{
|
||||
string result = "";
|
||||
|
||||
try
|
||||
{
|
||||
string data = "";
|
||||
if (System.IO.File.Exists(_standardFolder + _standardFileName))
|
||||
{
|
||||
using (System.IO.StreamReader file = new System.IO.StreamReader(_standardFolder + _standardFileName))
|
||||
{
|
||||
string line = "";
|
||||
|
||||
while ((line = file.ReadLine()) != null)
|
||||
{
|
||||
data += line;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = data;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to read data from file '" + _standardFolder + _standardFileName + "':" + e.Message);
|
||||
_valid = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ClearData()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.IO.File.WriteAllText(_standardFolder + _standardFileName, "");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to clear data: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateStandardFolderIfNotExists()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (System.IO.Directory.Exists(_standardFolder) == false)
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(_standardFolder);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to create folder: " + e.Message);
|
||||
_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateStandardFileIfNotExists()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (System.IO.File.Exists(_standardFolder + _standardFileName) == false)
|
||||
{
|
||||
System.IO.File.Create(_standardFolder + _standardFileName);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to create file: " + e.Message);
|
||||
_valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using EnvDTE;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
class FileUtility
|
||||
{
|
||||
public delegate void ErrorCallback(string message);
|
||||
|
||||
public static ErrorCallback _errorCallback = null;
|
||||
|
||||
/**
|
||||
* Returns true when file was found, false otherwise
|
||||
*/
|
||||
public static bool OpenSourceFile(DTE dte, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
dte.ItemOperations.OpenFile(fileName);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
|
||||
if (_errorCallback != null)
|
||||
{
|
||||
_errorCallback("Failed to open file at " + fileName);
|
||||
}
|
||||
|
||||
string message = "Failed to open file at " + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(fileName);
|
||||
Logging.Logging.LogError(message);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void GoToLine(DTE dte, int lineNumber, int columnNumber)
|
||||
{
|
||||
try
|
||||
{
|
||||
((EnvDTE.TextSelection)dte.ActiveDocument.Selection).MoveToLineAndOffset(lineNumber, columnNumber);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
|
||||
if (_errorCallback != null)
|
||||
{
|
||||
_errorCallback("Failed to set cursor to position [" + lineNumber.ToString() + "," + columnNumber.ToString() + "]");
|
||||
|
||||
string message = "Failed to set cursor to position [" + lineNumber.ToString() + "," + columnNumber.ToString() + "]";
|
||||
Logging.Logging.LogError(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetActiveDocumentName(DTE dte)
|
||||
{
|
||||
return dte.ActiveDocument.Name;
|
||||
}
|
||||
|
||||
public static string GetActiveDocumentPath(DTE dte)
|
||||
{
|
||||
return dte.ActiveDocument.Path;
|
||||
}
|
||||
|
||||
public static int GetActiveLineNumber(DTE dte)
|
||||
{
|
||||
return ((EnvDTE.TextSelection)dte.ActiveDocument.Selection).ActivePoint.Line;
|
||||
}
|
||||
|
||||
public static int GetActiveColumnNumber(DTE dte)
|
||||
{
|
||||
return ((EnvDTE.TextSelection)dte.ActiveDocument.Selection).ActivePoint.LineCharOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
class NetworkProtocolUtility
|
||||
{
|
||||
private static string s_divider = ">>";
|
||||
private static string s_setActiveTokenPrefix = "setActiveToken";
|
||||
private static string s_moveCursorPrefix = "moveCursor";
|
||||
private static string s_endOfMessageToken = "<EOM>";
|
||||
|
||||
private static string s_createProjectPrefix = "createProject"; // deprecate
|
||||
private static string s_createCDBProjectPrefix = "createCDBProject";
|
||||
private static string s_ideId = "vs";
|
||||
|
||||
private static string s_createCDBPrefix = "createCDB";
|
||||
|
||||
private static string s_pingPrefix = "ping";
|
||||
|
||||
public enum MESSAGE_TYPE
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
MOVE_CURSOR,
|
||||
CREATE_CDB,
|
||||
PING
|
||||
}
|
||||
|
||||
public class CursorPosition
|
||||
{
|
||||
private string _filePath = "";
|
||||
private int _lineNumber = 0;
|
||||
private int _columnNumber = 0;
|
||||
private bool _valid = false;
|
||||
|
||||
public string FilePath
|
||||
{
|
||||
get { return _filePath; }
|
||||
set { _filePath = value; }
|
||||
}
|
||||
|
||||
public int LineNumber
|
||||
{
|
||||
get { return _lineNumber; }
|
||||
set { _lineNumber = value; }
|
||||
}
|
||||
|
||||
public int ColumnNumber
|
||||
{
|
||||
get { return _columnNumber; }
|
||||
set { _columnNumber = value; }
|
||||
}
|
||||
|
||||
public bool Valid
|
||||
{
|
||||
get { return _valid; }
|
||||
set { _valid = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public class Ping
|
||||
{
|
||||
private string _id = "";
|
||||
private bool _valid = false;
|
||||
|
||||
public string Id
|
||||
{
|
||||
get { return _id; }
|
||||
set { _id = value; }
|
||||
}
|
||||
|
||||
public bool Valid
|
||||
{
|
||||
get { return _valid; }
|
||||
set { _valid = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public static string CreateActivateTokenMessage(string filePath, int lineNumber, int columnNumber)
|
||||
{
|
||||
string message = s_setActiveTokenPrefix;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += filePath;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += lineNumber.ToString();
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += columnNumber.ToString();
|
||||
|
||||
message += s_endOfMessageToken;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public static string CreateCreateProjectMessage(string solutionPath)
|
||||
{
|
||||
string message = s_createProjectPrefix;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += solutionPath;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += s_ideId;
|
||||
|
||||
message += s_endOfMessageToken;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public static string CreateCreateProjectMessage(string cdbPath, List<string> headerPaths)
|
||||
{
|
||||
string message = s_createCDBProjectPrefix;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += cdbPath;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
foreach(string path in headerPaths)
|
||||
{
|
||||
message += path;
|
||||
|
||||
message += s_divider;
|
||||
}
|
||||
|
||||
message += s_ideId;
|
||||
|
||||
message += s_endOfMessageToken;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public static string CreatePingMessage()
|
||||
{
|
||||
string message = s_pingPrefix;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += s_ideId;
|
||||
|
||||
message += s_endOfMessageToken;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public static MESSAGE_TYPE GetMessageType(string message)
|
||||
{
|
||||
List<string> tokens = GetMessageTokens(message);
|
||||
|
||||
if (tokens.Count > 0)
|
||||
{
|
||||
if (tokens[0] == s_createCDBPrefix)
|
||||
{
|
||||
return MESSAGE_TYPE.CREATE_CDB;
|
||||
}
|
||||
else if (tokens[0] == s_moveCursorPrefix)
|
||||
{
|
||||
return MESSAGE_TYPE.MOVE_CURSOR;
|
||||
}
|
||||
else if (tokens[0] == s_pingPrefix)
|
||||
{
|
||||
return MESSAGE_TYPE.PING;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MESSAGE_TYPE.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return MESSAGE_TYPE.UNKNOWN;
|
||||
}
|
||||
|
||||
public static CursorPosition ParseSetCursorMessage(string message)
|
||||
{
|
||||
CursorPosition result = new CursorPosition();
|
||||
|
||||
List<string> tokens = GetMessageTokens(message);
|
||||
|
||||
if(tokens.Count != 4)
|
||||
{
|
||||
Logging.Logging.LogError("Invalid message: " + message);
|
||||
Logging.Logging.LogError("Invalid token count for 'move cursor' message. Expected 4, but got " + tokens.Count.ToString());
|
||||
return result;
|
||||
}
|
||||
|
||||
if(tokens[0] != s_moveCursorPrefix)
|
||||
{
|
||||
Logging.Logging.LogError("Invalid message: " + message);
|
||||
Logging.Logging.LogError("Invalid message type. Expected '" + s_moveCursorPrefix + "' but got '" + tokens[0] + "'");
|
||||
return result;
|
||||
}
|
||||
|
||||
result.FilePath = tokens[1];
|
||||
|
||||
int lineNumber = 0;
|
||||
if(int.TryParse(tokens[2], out lineNumber))
|
||||
{
|
||||
result.LineNumber = lineNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogError("Invalid message: " + message);
|
||||
Logging.Logging.LogError("Failed to parse line number");
|
||||
return result;
|
||||
}
|
||||
|
||||
int columnNumber = 0;
|
||||
if(int.TryParse(tokens[3], out columnNumber))
|
||||
{
|
||||
result.ColumnNumber = columnNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogError("Invalid message: " + message);
|
||||
Logging.Logging.LogError("Failed to parse column number");
|
||||
return result;
|
||||
}
|
||||
|
||||
result.Valid = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Ping ParsePingMessage(string message)
|
||||
{
|
||||
Ping result = new Ping();
|
||||
|
||||
List<string> tokens = GetMessageTokens(message);
|
||||
|
||||
if(tokens.Count != 2)
|
||||
{
|
||||
Logging.Logging.LogError("Invalid message: " + message);
|
||||
Logging.Logging.LogError("Invalid token count for 'ping' message. Expected 2, but got " + tokens.Count.ToString());
|
||||
return result;
|
||||
}
|
||||
|
||||
if (tokens[0] != s_pingPrefix)
|
||||
{
|
||||
Logging.Logging.LogError("Invalid message: " + message);
|
||||
Logging.Logging.LogError("Invalid message type. Expected '" + s_pingPrefix + "' but got '" + tokens[0] + "'");
|
||||
return result;
|
||||
}
|
||||
|
||||
result.Id = tokens[1];
|
||||
result.Valid = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<string> GetMessageTokens(string message)
|
||||
{
|
||||
List<string> tokens = new List<string>();
|
||||
|
||||
if(RemoveEOMString(ref message))
|
||||
{
|
||||
tokens = message.Split(s_divider.ToCharArray()).ToList();
|
||||
|
||||
// removing empty strings
|
||||
List<string> cleanTokens = new List<string>();
|
||||
foreach(string token in tokens)
|
||||
{
|
||||
if(token.Length > 0)
|
||||
{
|
||||
cleanTokens.Add(token);
|
||||
}
|
||||
}
|
||||
|
||||
tokens = cleanTokens;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogError("");
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// returns false if no EOM string was found
|
||||
private static bool RemoveEOMString(ref string message)
|
||||
{
|
||||
if (message.IndexOf(s_endOfMessageToken) > -1)
|
||||
{
|
||||
message = message.Substring(0, message.IndexOf(s_endOfMessageToken));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
public class StateObject
|
||||
{
|
||||
public Socket _workSocket = null;
|
||||
public const int _bufferSize = 1024;
|
||||
public byte[] _buffer = new byte[_bufferSize];
|
||||
public StringBuilder _stringBuilder = new StringBuilder();
|
||||
}
|
||||
|
||||
public class AsynchronousSocketListener
|
||||
{
|
||||
public static ManualResetEvent _allDone = new ManualResetEvent(false);
|
||||
|
||||
public delegate void OnReadCallback(string message);
|
||||
|
||||
public static OnReadCallback _onReadCallback = null;
|
||||
public static OnReadCallback _onErrorCallback = null;
|
||||
|
||||
private static string _endOfMessageToken = "<EOM>";
|
||||
|
||||
public static uint _port = 6666;
|
||||
|
||||
public AsynchronousSocketListener()
|
||||
{
|
||||
}
|
||||
|
||||
public void DoWork()
|
||||
{
|
||||
StartListening();
|
||||
}
|
||||
|
||||
public static void StartListening()
|
||||
{
|
||||
const string ipAddressString = "127.0.0.1";
|
||||
|
||||
byte[] bytes = new Byte[1024];
|
||||
|
||||
IPAddress ipAddress = IPAddress.Parse(ipAddressString);
|
||||
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, (int)_port);
|
||||
|
||||
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
|
||||
try
|
||||
{
|
||||
listener.Bind(localEndPoint);
|
||||
listener.Listen(100);
|
||||
|
||||
while (true)
|
||||
{
|
||||
_allDone.Reset();
|
||||
|
||||
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
|
||||
_allDone.WaitOne();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AcceptCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
_allDone.Set();
|
||||
|
||||
Socket listener = (Socket)ar.AsyncState;
|
||||
Socket handler = listener.EndAccept(ar);
|
||||
|
||||
StateObject state = new StateObject();
|
||||
state._workSocket = handler;
|
||||
handler.BeginReceive(state._buffer, 0, StateObject._bufferSize, 0, new AsyncCallback(ReadCallback), state);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReadCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
string content = String.Empty;
|
||||
|
||||
StateObject state = (StateObject)ar.AsyncState;
|
||||
Socket handler = state._workSocket;
|
||||
|
||||
int bytesRead = handler.EndReceive(ar);
|
||||
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
state._stringBuilder.Append(Encoding.ASCII.GetString(state._buffer, 0, bytesRead));
|
||||
|
||||
content = state._stringBuilder.ToString();
|
||||
if (content.IndexOf(_endOfMessageToken) > -1)
|
||||
{
|
||||
if (_onReadCallback != null)
|
||||
{
|
||||
_onReadCallback(content);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handler.BeginReceive(state._buffer, 0, StateObject._bufferSize, 0, new AsyncCallback(ReadCallback), state);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Excpetion: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Send(Socket handler, String data)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] byteData = Encoding.ASCII.GetBytes(data);
|
||||
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Excpetion: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket handler = (Socket)ar.AsyncState;
|
||||
|
||||
int bytesSent = handler.EndSend(ar);
|
||||
Logging.Logging.LogInfo("Sent " + bytesSent.ToString() + " bytes to client.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Excpetion: " + e.Message);
|
||||
|
||||
if (_onErrorCallback != null)
|
||||
{
|
||||
_onErrorCallback(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AsynchronousClient
|
||||
{
|
||||
public static uint _port = 6667;
|
||||
|
||||
private static ManualResetEvent connectDone = new ManualResetEvent(false);
|
||||
private static ManualResetEvent sendDone = new ManualResetEvent(false);
|
||||
|
||||
private static String response = String.Empty;
|
||||
|
||||
public static AsynchronousSocketListener.OnReadCallback _onErrorCallback = null;
|
||||
|
||||
public static void Send(string message)
|
||||
{
|
||||
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
|
||||
IPEndPoint remoteEP = new IPEndPoint(ipAddress, (int)_port);
|
||||
|
||||
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
|
||||
try
|
||||
{
|
||||
IAsyncResult ar = client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
|
||||
if (!connectDone.WaitOne(2000))
|
||||
{
|
||||
client.EndConnect(ar);
|
||||
client.Shutdown(SocketShutdown.Both);
|
||||
client.Close();
|
||||
|
||||
Logging.Logging.LogWarning("Connection timed out, message was not sent");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Send(client, message);
|
||||
sendDone.WaitOne();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(client.Connected)
|
||||
{
|
||||
client.Shutdown(SocketShutdown.Both);
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ConnectCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket client = (Socket)ar.AsyncState;
|
||||
|
||||
if (client.Connected == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.EndConnect(ar);
|
||||
|
||||
connectDone.Set();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Excpetion: " + e.Message);
|
||||
|
||||
if (_onErrorCallback != null)
|
||||
{
|
||||
_onErrorCallback(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Send(Socket client, String data)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] byteData = Encoding.ASCII.GetBytes(data);
|
||||
|
||||
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket client = (Socket)ar.AsyncState;
|
||||
|
||||
int bytesSent = client.EndSend(ar);
|
||||
|
||||
sendDone.Set();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Excpetion: " + e.Message);
|
||||
|
||||
if (_onErrorCallback != null)
|
||||
{
|
||||
if (e is ObjectDisposedException)
|
||||
{
|
||||
// get this exception every once in a while
|
||||
// doesn't seem to do much, no idea yet why it's there to begin with
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
_onErrorCallback(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using EnvDTE;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
public class ProjectUtility
|
||||
{
|
||||
public static bool ContainsCFiles(Project project)
|
||||
{
|
||||
List<ProjectItem> projectItems = GetProjectItems(project);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (EnvDTE.ProjectItem item in projectItems)
|
||||
{
|
||||
if (item.FileCodeModel != null && item.FileCodeModel.Language == CodeModelLanguageConstants.vsCMLanguageVC)
|
||||
{
|
||||
string extension = item.Properties.Item("Extension").Value.ToString();
|
||||
if (extension == ".c")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static public List<ProjectItem> GetProjectItems(Project project)
|
||||
{
|
||||
List<ProjectItem> items = new List<ProjectItem>();
|
||||
|
||||
IEnumerator itemEnumerator = project.ProjectItems.GetEnumerator();
|
||||
|
||||
while (itemEnumerator.MoveNext())
|
||||
{
|
||||
ProjectItem currentItem = (ProjectItem)itemEnumerator.Current;
|
||||
items.Add(GetProjectSubItemsRecursive(currentItem, ref items));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
static private ProjectItem GetProjectSubItemsRecursive(ProjectItem item, ref List<ProjectItem> projectItems)
|
||||
{
|
||||
if (item.ProjectItems == null)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
IEnumerator items = item.ProjectItems.GetEnumerator();
|
||||
|
||||
while (items.MoveNext())
|
||||
{
|
||||
ProjectItem currentItem = (ProjectItem)items.Current;
|
||||
projectItems.Add(GetProjectSubItemsRecursive(currentItem, ref projectItems));
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
// returns true if the project was reloaded, false if the project did not need to be reloaded
|
||||
static public Guid ReloadProject(Project project)
|
||||
{
|
||||
Logging.Logging.LogInfo("Attempting to reload project");
|
||||
|
||||
try
|
||||
{
|
||||
if (project != null && project.Kind == EnvDTE.Constants.vsProjectKindUnmodeled)
|
||||
{
|
||||
DTE dte = project.DTE;
|
||||
|
||||
ServiceProvider sp = new ServiceProvider(dte as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
|
||||
IVsSolution vsSolution = sp.GetService(typeof(SVsSolution)) as IVsSolution;
|
||||
|
||||
IVsHierarchy hierarchy;
|
||||
|
||||
string solutionDirectory = "";
|
||||
string solutionFile = "";
|
||||
string userOptions = "";
|
||||
vsSolution.GetSolutionInfo(out solutionDirectory, out solutionFile, out userOptions);
|
||||
|
||||
vsSolution.GetProjectOfUniqueName(solutionDirectory + project.UniqueName, out hierarchy);
|
||||
|
||||
if (hierarchy != null)
|
||||
{
|
||||
Guid projectGuid;
|
||||
|
||||
hierarchy.GetGuidProperty(
|
||||
VSConstants.VSITEMID_ROOT,
|
||||
(int)__VSHPROPID.VSHPROPID_ProjectIDGuid,
|
||||
out projectGuid);
|
||||
|
||||
if (projectGuid != null)
|
||||
{
|
||||
Logging.Logging.LogInfo("Project '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "' with GUID {" + projectGuid.ToString() + "} loaded.");
|
||||
(vsSolution as IVsSolution4).ReloadProject(projectGuid);
|
||||
return projectGuid;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogError("Failed to load project '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogError("Failed to retreive IVsHierarchy. Can't load project '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (project == null)
|
||||
{
|
||||
Logging.Logging.LogWarning("Project is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogInfo("Project '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "' is already loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
static public void UnloadProject(Guid guid, DTE dte)
|
||||
{
|
||||
Logging.Logging.LogInfo("Attempting to unload project with GUID {" + guid.ToString() + "}");
|
||||
|
||||
if (dte == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ServiceProvider sp = new ServiceProvider(dte as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
|
||||
IVsSolution vsSolution = sp.GetService(typeof(SVsSolution)) as IVsSolution;
|
||||
|
||||
(vsSolution as IVsSolution4).UnloadProject(guid, (uint)_VSProjectUnloadStatus.UNLOADSTATUS_UnloadedByUser);
|
||||
|
||||
Logging.Logging.LogInfo("Done unloading project with GUID {" + guid.ToString() + "}");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
class QueuedFileWriter
|
||||
{
|
||||
private bool _working = false;
|
||||
Thread _workerThread = null;
|
||||
|
||||
private static ReaderWriterLockSlim _statusLock = new ReaderWriterLockSlim();
|
||||
private static ReaderWriterLockSlim _queueLock = new ReaderWriterLockSlim();
|
||||
private static ReaderWriterLockSlim _fileLock = new ReaderWriterLockSlim();
|
||||
|
||||
private Queue<string> _inputQueue = new Queue<string>();
|
||||
private Queue<string> _outputQueue = new Queue<string>();
|
||||
|
||||
private string _targetDirectory = "";
|
||||
private string _fileName = "";
|
||||
|
||||
private int _messagesReceived = 0;
|
||||
private int _messageWrittenCount = 0;
|
||||
|
||||
public string TargetDirectory
|
||||
{
|
||||
get { return _targetDirectory; }
|
||||
set { _targetDirectory = value; }
|
||||
}
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get { return _fileName; }
|
||||
set { _fileName = value; }
|
||||
}
|
||||
|
||||
public void pushMessage(string message)
|
||||
{
|
||||
_queueLock.EnterWriteLock();
|
||||
_messagesReceived++;
|
||||
try
|
||||
{
|
||||
_inputQueue.Enqueue(message);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError(e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_queueLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void startWorking()
|
||||
{
|
||||
_statusLock.EnterReadLock();
|
||||
if (_working == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_statusLock.ExitReadLock();
|
||||
|
||||
|
||||
_statusLock.EnterWriteLock();
|
||||
_working = true;
|
||||
_workerThread = new Thread(new ThreadStart(work));
|
||||
_workerThread.Start();
|
||||
_statusLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
public void stopWorking()
|
||||
{
|
||||
_statusLock.EnterWriteLock();
|
||||
_working = false;
|
||||
_statusLock.ExitWriteLock();
|
||||
|
||||
if(_workerThread != null)
|
||||
{
|
||||
_workerThread.Join();
|
||||
}
|
||||
|
||||
// write remaining messages if stop was called
|
||||
_queueLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
writeQueueToFile(ref _inputQueue);
|
||||
writeQueueToFile(ref _outputQueue);
|
||||
|
||||
Logging.Logging.LogInfo("final commit done");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError(e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_queueLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
Logging.Logging.LogInfo("Messages received: " + _messagesReceived);
|
||||
Logging.Logging.LogInfo("Messages written: " + _messageWrittenCount);
|
||||
}
|
||||
|
||||
private void work()
|
||||
{
|
||||
bool working = true;
|
||||
|
||||
while(working)
|
||||
{
|
||||
commit();
|
||||
|
||||
_statusLock.EnterReadLock();
|
||||
working = _working;
|
||||
_statusLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
private void commit()
|
||||
{
|
||||
_queueLock.EnterWriteLock();
|
||||
|
||||
Queue<string> tmpQueue = _inputQueue;
|
||||
_inputQueue = _outputQueue;
|
||||
_outputQueue = tmpQueue;
|
||||
|
||||
_queueLock.ExitWriteLock();
|
||||
|
||||
|
||||
writeQueueToFile(ref _outputQueue);
|
||||
}
|
||||
|
||||
private void writeQueueToFile(ref Queue<string> messageQueue)
|
||||
{
|
||||
_fileLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
while(messageQueue.Count > 0)
|
||||
{
|
||||
_messageWrittenCount++;
|
||||
|
||||
string message = messageQueue.Dequeue();
|
||||
|
||||
File.AppendAllText(_targetDirectory + "\\" + _fileName, message);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError(e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_fileLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EnvDTE;
|
||||
using EnvDTE80;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Microsoft.VisualStudio;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
public class SolutionUtility
|
||||
{
|
||||
[DllImport("ole32.dll")]
|
||||
private static extern void CreateBindCtx(int reserved, out IBindCtx bindCtx);
|
||||
[DllImport("ole32.dll")]
|
||||
private static extern void GetRunningObjectTable(int reserved, out IRunningObjectTable runningObjectTable);
|
||||
|
||||
public class SolutionStructure
|
||||
{
|
||||
public class Node
|
||||
{
|
||||
public enum NodeType
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
PROJECT,
|
||||
FOLDER
|
||||
};
|
||||
|
||||
public string Name = "";
|
||||
public Project Project = null;
|
||||
public Object UserData = null;
|
||||
|
||||
public virtual NodeType GetNodeType() { throw (new NotImplementedException()); }
|
||||
}
|
||||
|
||||
public class FolderNode : Node
|
||||
{
|
||||
public List<Node> SubNodes = new List<Node>();
|
||||
|
||||
public override NodeType GetNodeType() { return NodeType.FOLDER; }
|
||||
}
|
||||
|
||||
public class ProjectNode : Node
|
||||
{
|
||||
public bool Include = false;
|
||||
|
||||
public override NodeType GetNodeType() { return NodeType.PROJECT; }
|
||||
}
|
||||
|
||||
public List<Node> Nodes = new List<Node>();
|
||||
}
|
||||
|
||||
public static String GetSolutionPath(DTE dte)
|
||||
{
|
||||
try
|
||||
{
|
||||
EnvDTE.Solution solution = dte.Solution;
|
||||
|
||||
return solution.FullName;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
|
||||
return "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
public static SolutionStructure GetSolutionVCProjects(DTE dte)
|
||||
{
|
||||
return GetProjectStructureRecursive(dte); ;
|
||||
}
|
||||
|
||||
public static SolutionStructure GetProjectStructureRecursive(DTE dte)
|
||||
{
|
||||
EnvDTE.Solution solution = dte.Solution;
|
||||
EnvDTE.Projects solutionProjects = solution.Projects;
|
||||
|
||||
List<Guid> guids = new List<Guid>();
|
||||
|
||||
SolutionStructure projectStructure = new SolutionStructure();
|
||||
|
||||
foreach(Project project in solutionProjects)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (project.Kind == EnvDTE.Constants.vsProjectKindUnmodeled) // not loaded
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check it's a c/c++ project
|
||||
if (project.CodeModel != null)
|
||||
{
|
||||
if (project.CodeModel.Language != CodeModelLanguageConstants.vsCMLanguageVC)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (project.Kind == "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
|
||||
{
|
||||
SolutionStructure.ProjectNode projectNode = new SolutionStructure.ProjectNode();
|
||||
projectNode.Name = project.Name;
|
||||
projectNode.Project = project;
|
||||
projectNode.Include = false;
|
||||
|
||||
projectStructure.Nodes.Add(projectNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
SolutionStructure.Node folderNode = GetSubProjects(project);
|
||||
|
||||
if (folderNode != null)
|
||||
{
|
||||
projectStructure.Nodes.Add(folderNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogWarning("Subnode was NULL");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return projectStructure;
|
||||
}
|
||||
|
||||
private static SolutionStructure.Node GetSubProjects(EnvDTE.Project project)
|
||||
{
|
||||
ProjectItems projectItems = project.ProjectItems;
|
||||
List<Project> items = new List<Project>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (ProjectItem item in projectItems)
|
||||
{
|
||||
Project p = item.Object as Project;
|
||||
if (p != null)
|
||||
{
|
||||
items.Add(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (items.Count > 0)
|
||||
{
|
||||
SolutionStructure.FolderNode folderNode = new SolutionStructure.FolderNode();
|
||||
folderNode.Name = project.Name;
|
||||
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
Project item = items[i];
|
||||
|
||||
SolutionStructure.Node subFolderNode = GetSubProjects(item);
|
||||
|
||||
if(subFolderNode != null)
|
||||
{
|
||||
folderNode.SubNodes.Add(subFolderNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogWarning("SubNode was NULL");
|
||||
}
|
||||
}
|
||||
|
||||
return folderNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
SolutionStructure.ProjectNode projectNode = new SolutionStructure.ProjectNode();
|
||||
projectNode.Name = project.Name;
|
||||
projectNode.Project = project;
|
||||
projectNode.Include = false;
|
||||
|
||||
return projectNode;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: remove when old project parsing is retired
|
||||
public static List<String> GetSolutionProjectsFullNames(DTE dte)
|
||||
{
|
||||
List<String> projectNames = new List<String>();
|
||||
|
||||
EnvDTE.Solution solution = dte.Solution;
|
||||
EnvDTE.Projects projects = solution.Projects;
|
||||
|
||||
List<Guid> guids = new List<Guid>();
|
||||
|
||||
foreach (EnvDTE.Project project in projects)
|
||||
{
|
||||
guids.Add(ProjectUtility.ReloadProject(project));
|
||||
}
|
||||
|
||||
projects = solution.Projects;
|
||||
|
||||
foreach (EnvDTE.Project project in projects)
|
||||
{
|
||||
projectNames.Add(project.FullName);
|
||||
}
|
||||
|
||||
foreach (Guid guid in guids)
|
||||
{
|
||||
ProjectUtility.UnloadProject(guid, dte);
|
||||
}
|
||||
|
||||
return projectNames;
|
||||
}
|
||||
|
||||
public static List<String> GetSolutionLanguages(DTE dte)
|
||||
{
|
||||
List<String> languages = new List<String>();
|
||||
|
||||
List<Project> projects = GetSolutionProjectList(dte);
|
||||
|
||||
foreach (EnvDTE.Project project in projects)
|
||||
{
|
||||
if (project.CodeModel != null)
|
||||
{
|
||||
string language = project.CodeModel.Language;
|
||||
languages.Add(language);
|
||||
}
|
||||
}
|
||||
|
||||
languages = languages.Distinct().ToList();
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
public static bool GetSolutionIsSaved(DTE dte)
|
||||
{
|
||||
try
|
||||
{
|
||||
EnvDTE.Solution solution = dte.Solution;
|
||||
|
||||
return solution.Saved;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<List<string>> GetConfigurationAndPlatformNames(DTE dte)
|
||||
{
|
||||
List<List<string>> result = new List<List<string>>();
|
||||
List<string> configNames = new List<string>();
|
||||
List<string> platformNames = new List<string>();
|
||||
|
||||
DTE2 dte2 = SolutionUtility.GetDTE2(dte);
|
||||
|
||||
if(dte2 == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
EnvDTE80.Solution2 solution = (EnvDTE80.Solution2)dte2.Solution;
|
||||
if(solution == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
EnvDTE80.SolutionBuild2 solutionBuild = (EnvDTE80.SolutionBuild2)solution.SolutionBuild;
|
||||
if(solutionBuild == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
foreach (SolutionConfiguration2 solutionConfiguration in solutionBuild.SolutionConfigurations)
|
||||
{
|
||||
foreach (SolutionContext context in solutionConfiguration.SolutionContexts)
|
||||
{
|
||||
string configurationName = context.ConfigurationName;
|
||||
configNames.Add(configurationName);
|
||||
|
||||
string platformName = context.PlatformName;
|
||||
platformNames.Add(platformName);
|
||||
}
|
||||
}
|
||||
|
||||
configNames = configNames.Distinct().ToList();
|
||||
platformNames = platformNames.Distinct().ToList();
|
||||
|
||||
result.Add(configNames);
|
||||
result.Add(platformNames);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static DTE2 GetDTE2(DTE dte)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<DTE2> dte2List = new List<DTE2>();
|
||||
|
||||
IRunningObjectTable runningObjectTable = null;
|
||||
GetRunningObjectTable(0, out runningObjectTable);
|
||||
|
||||
IEnumMoniker enumMoniker = null;
|
||||
runningObjectTable.EnumRunning(out enumMoniker);
|
||||
|
||||
enumMoniker.Reset();
|
||||
IntPtr fetched = IntPtr.Zero;
|
||||
IMoniker[] moniker = new IMoniker[1];
|
||||
|
||||
while (enumMoniker.Next(1, moniker, fetched) == 0)
|
||||
{
|
||||
IBindCtx bindCtx = null;
|
||||
CreateBindCtx(0, out bindCtx);
|
||||
|
||||
string displayName = "";
|
||||
moniker[0].GetDisplayName(bindCtx, null, out displayName);
|
||||
// add all VisualStudio ROT entries to list
|
||||
if (displayName.StartsWith("!VisualStudio"))
|
||||
{
|
||||
object comObject;
|
||||
runningObjectTable.GetObject(moniker[0], out comObject);
|
||||
dte2List.Add((DTE2)comObject);
|
||||
}
|
||||
}
|
||||
|
||||
// find the correct dte2 instance (each running VS instance has one...)
|
||||
KeyValuePair<DTE2, int> maxMatch = new KeyValuePair<DTE2, int>(null, 0);
|
||||
foreach (DTE2 dte2 in dte2List)
|
||||
{
|
||||
int m = StringUtility.GetMatchingCharsFromStart(dte.Solution.FullName, dte2.Solution.FullName);
|
||||
if (m > maxMatch.Value)
|
||||
{
|
||||
maxMatch = new KeyValuePair<DTE2, int>(dte2, m);
|
||||
}
|
||||
}
|
||||
|
||||
return maxMatch.Key;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static public bool ContainsCFiles(DTE dte)
|
||||
{
|
||||
List<Project> projects = GetSolutionProjectList(dte); // dte.Solution.Projects;
|
||||
|
||||
foreach (Project project in projects)
|
||||
{
|
||||
if(ProjectUtility.ContainsCFiles(project) == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static public List<EnvDTE.Project> GetSolutionProjectList(DTE dte)
|
||||
{
|
||||
List<EnvDTE.Project> solutionProjects = new List<EnvDTE.Project>();
|
||||
|
||||
try
|
||||
{
|
||||
SolutionStructure solutionStructure = GetProjectStructureRecursive(dte);
|
||||
|
||||
Stack<SolutionStructure.Node> nodeStack = new Stack<Utility.SolutionUtility.SolutionStructure.Node>();
|
||||
foreach (SolutionStructure.Node node in solutionStructure.Nodes)
|
||||
{
|
||||
nodeStack.Push(node);
|
||||
}
|
||||
|
||||
while (nodeStack.Count > 0)
|
||||
{
|
||||
Utility.SolutionUtility.SolutionStructure.Node node = nodeStack.Pop();
|
||||
|
||||
string name = node.Name;
|
||||
|
||||
if (node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.PROJECT)
|
||||
{
|
||||
solutionProjects.Add(node.Project);
|
||||
}
|
||||
else if (node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.FOLDER)
|
||||
{
|
||||
Utility.SolutionUtility.SolutionStructure.FolderNode folderNode = node as Utility.SolutionUtility.SolutionStructure.FolderNode;
|
||||
foreach (Utility.SolutionUtility.SolutionStructure.Node subNode in folderNode.SubNodes)
|
||||
{
|
||||
nodeStack.Push(subNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return solutionProjects;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
|
||||
return new List<EnvDTE.Project>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
class StringUtility
|
||||
{
|
||||
static public Tuple<int, int> FindFirstRange(string text, string startTag, string endTag)
|
||||
{
|
||||
if(startTag.Length > 0 && endTag.Length > 0 && (startTag.Length + endTag.Length) < text.Length)
|
||||
{
|
||||
int start = text.IndexOf(startTag);
|
||||
int end = text.IndexOf(endTag);
|
||||
|
||||
// just check wheter both, start and end, are valid and the end tag occurs after the start tag
|
||||
if(start > -1 && end > -1 && end > start)
|
||||
{
|
||||
return new Tuple<int, int>(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static public int GetMatchingCharsFromStart(string a, string b)
|
||||
{
|
||||
int matchingChars = 0;
|
||||
|
||||
if (a != string.Empty)
|
||||
{
|
||||
a = a.ToLower();
|
||||
}
|
||||
else
|
||||
{
|
||||
return matchingChars;
|
||||
}
|
||||
|
||||
if (b != string.Empty)
|
||||
{
|
||||
b = b.ToLower();
|
||||
}
|
||||
else
|
||||
{
|
||||
return matchingChars;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Math.Min(a.Length, b.Length); i++)
|
||||
{
|
||||
if (!char.Equals(a[i], b[i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
matchingChars++;
|
||||
}
|
||||
}
|
||||
|
||||
return matchingChars;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Utility
|
||||
{
|
||||
class SystemUtility
|
||||
{
|
||||
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
||||
static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
||||
static extern IntPtr SetActiveWindow(IntPtr hWnd);
|
||||
|
||||
public static void GetWindowFocus()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
|
||||
IntPtr windowHandle = process.MainWindowHandle;
|
||||
|
||||
if (windowHandle != null)
|
||||
{
|
||||
SetForegroundWindow(windowHandle);
|
||||
SetActiveWindow(windowHandle);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Exception: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OpenWindowsExplorerAtDirectory(string directory)
|
||||
{
|
||||
System.Diagnostics.Process.Start(directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
VS SDK Notes: This resx file contains the resources that will be consumed from your package by Visual Studio.
|
||||
For example, Visual Studio will attempt to load resource '400' from this resource stream when it needs to
|
||||
load your package's icon. Because Visual Studio will always look in the VSPackage.resources stream first for
|
||||
resources it needs, you should put additional resources that Visual Studio will load directly into this resx
|
||||
file.
|
||||
|
||||
Resources that you would like to access directly from your package in a strong-typed fashion should be stored
|
||||
in Resources.resx or another resx file.
|
||||
-->
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="110" xml:space="preserve">
|
||||
<value>SourcetrailPlugin</value>
|
||||
</data>
|
||||
<data name="112" xml:space="preserve">
|
||||
<value>Sourcetrail plugin test</value>
|
||||
</data>
|
||||
</root>
|
||||
Generated
+277
@@ -0,0 +1,277 @@
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
partial class ProjectSetupWindow
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProjectSetupWindow));
|
||||
this.buttonCancel = new System.Windows.Forms.Button();
|
||||
this.buttonCreate = new System.Windows.Forms.Button();
|
||||
this.comboBoxConfiguration = new System.Windows.Forms.ComboBox();
|
||||
this.comboBoxPlatform = new System.Windows.Forms.ComboBox();
|
||||
this.labelConfiguration = new System.Windows.Forms.Label();
|
||||
this.labelPlatform = new System.Windows.Forms.Label();
|
||||
this.buttonSelectAll = new System.Windows.Forms.Button();
|
||||
this.labelSelectProject = new System.Windows.Forms.Label();
|
||||
this.folderBrowserTargetDirectory = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.textBoxTargetDirectory = new System.Windows.Forms.TextBox();
|
||||
this.buttonSelect = new System.Windows.Forms.Button();
|
||||
this.textBoxFileName = new System.Windows.Forms.TextBox();
|
||||
this.labelFileName = new System.Windows.Forms.Label();
|
||||
this.labelFileNameEnding = new System.Windows.Forms.Label();
|
||||
this.helpProvider1 = new System.Windows.Forms.HelpProvider();
|
||||
this.comboBoxCStandard = new System.Windows.Forms.ComboBox();
|
||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
|
||||
this.labelCStandard = new System.Windows.Forms.Label();
|
||||
this.treeViewProjects = new System.Windows.Forms.TreeView();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// buttonCancel
|
||||
//
|
||||
this.helpProvider1.SetHelpString(this.buttonCancel, "Abort creation of the CDB");
|
||||
this.buttonCancel.Location = new System.Drawing.Point(12, 413);
|
||||
this.buttonCancel.Name = "buttonCancel";
|
||||
this.helpProvider1.SetShowHelp(this.buttonCancel, true);
|
||||
this.buttonCancel.Size = new System.Drawing.Size(92, 23);
|
||||
this.buttonCancel.TabIndex = 9;
|
||||
this.buttonCancel.Text = "Cancel";
|
||||
this.toolTip1.SetToolTip(this.buttonCancel, "Abort creation of the CDB");
|
||||
this.buttonCancel.UseVisualStyleBackColor = true;
|
||||
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
|
||||
//
|
||||
// buttonCreate
|
||||
//
|
||||
this.helpProvider1.SetHelpString(this.buttonCreate, "Start creation of the CDB");
|
||||
this.buttonCreate.Location = new System.Drawing.Point(178, 413);
|
||||
this.buttonCreate.Name = "buttonCreate";
|
||||
this.helpProvider1.SetShowHelp(this.buttonCreate, true);
|
||||
this.buttonCreate.Size = new System.Drawing.Size(92, 23);
|
||||
this.buttonCreate.TabIndex = 8;
|
||||
this.buttonCreate.Text = "Create";
|
||||
this.toolTip1.SetToolTip(this.buttonCreate, "Start creation of the CDB");
|
||||
this.buttonCreate.UseVisualStyleBackColor = true;
|
||||
this.buttonCreate.Click += new System.EventHandler(this.buttonCreate_Click);
|
||||
//
|
||||
// comboBoxConfiguration
|
||||
//
|
||||
this.comboBoxConfiguration.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxConfiguration.FormattingEnabled = true;
|
||||
this.helpProvider1.SetHelpKeyword(this.comboBoxConfiguration, "Build configuration for CDB");
|
||||
this.helpProvider1.SetHelpString(this.comboBoxConfiguration, "The selected build configuration determines the compile flags for the CDB");
|
||||
this.comboBoxConfiguration.Location = new System.Drawing.Point(87, 277);
|
||||
this.comboBoxConfiguration.Name = "comboBoxConfiguration";
|
||||
this.helpProvider1.SetShowHelp(this.comboBoxConfiguration, true);
|
||||
this.comboBoxConfiguration.Size = new System.Drawing.Size(183, 21);
|
||||
this.comboBoxConfiguration.TabIndex = 3;
|
||||
this.toolTip1.SetToolTip(this.comboBoxConfiguration, "The selected build configuration determines the compile flags for the CDB");
|
||||
//
|
||||
// comboBoxPlatform
|
||||
//
|
||||
this.comboBoxPlatform.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxPlatform.FormattingEnabled = true;
|
||||
this.helpProvider1.SetHelpString(this.comboBoxPlatform, "The target platform determines some compiler flags included in the CDB");
|
||||
this.comboBoxPlatform.Location = new System.Drawing.Point(87, 304);
|
||||
this.comboBoxPlatform.Name = "comboBoxPlatform";
|
||||
this.helpProvider1.SetShowHelp(this.comboBoxPlatform, true);
|
||||
this.comboBoxPlatform.Size = new System.Drawing.Size(183, 21);
|
||||
this.comboBoxPlatform.TabIndex = 4;
|
||||
this.toolTip1.SetToolTip(this.comboBoxPlatform, "The target platform determines some compiler flags included in the CDB");
|
||||
//
|
||||
// labelConfiguration
|
||||
//
|
||||
this.labelConfiguration.AutoSize = true;
|
||||
this.labelConfiguration.Location = new System.Drawing.Point(12, 280);
|
||||
this.labelConfiguration.Name = "labelConfiguration";
|
||||
this.labelConfiguration.Size = new System.Drawing.Size(69, 13);
|
||||
this.labelConfiguration.TabIndex = 6;
|
||||
this.labelConfiguration.Text = "Configuration";
|
||||
//
|
||||
// labelPlatform
|
||||
//
|
||||
this.labelPlatform.AutoSize = true;
|
||||
this.labelPlatform.Location = new System.Drawing.Point(12, 307);
|
||||
this.labelPlatform.Name = "labelPlatform";
|
||||
this.labelPlatform.Size = new System.Drawing.Size(45, 13);
|
||||
this.labelPlatform.TabIndex = 7;
|
||||
this.labelPlatform.Text = "Platform";
|
||||
//
|
||||
// buttonSelectAll
|
||||
//
|
||||
this.helpProvider1.SetHelpString(this.buttonSelectAll, "Select all projects if not all are ticked. Deselect all otherwise");
|
||||
this.buttonSelectAll.Location = new System.Drawing.Point(178, 248);
|
||||
this.buttonSelectAll.Name = "buttonSelectAll";
|
||||
this.helpProvider1.SetShowHelp(this.buttonSelectAll, true);
|
||||
this.buttonSelectAll.Size = new System.Drawing.Size(92, 23);
|
||||
this.buttonSelectAll.TabIndex = 2;
|
||||
this.buttonSelectAll.Text = "De/Select All";
|
||||
this.toolTip1.SetToolTip(this.buttonSelectAll, "Select all projects if not all are ticked. Deselect all otherwise");
|
||||
this.buttonSelectAll.UseVisualStyleBackColor = true;
|
||||
this.buttonSelectAll.Click += new System.EventHandler(this.buttonSelectAll_Click);
|
||||
//
|
||||
// labelSelectProject
|
||||
//
|
||||
this.labelSelectProject.AutoSize = true;
|
||||
this.labelSelectProject.Location = new System.Drawing.Point(9, 9);
|
||||
this.labelSelectProject.Name = "labelSelectProject";
|
||||
this.labelSelectProject.Size = new System.Drawing.Size(78, 13);
|
||||
this.labelSelectProject.TabIndex = 9;
|
||||
this.labelSelectProject.Text = "Select Projects";
|
||||
this.labelSelectProject.Click += new System.EventHandler(this.label1_Click);
|
||||
//
|
||||
// textBoxTargetDirectory
|
||||
//
|
||||
this.helpProvider1.SetHelpString(this.textBoxTargetDirectory, "Target directory where the CDB will be stored");
|
||||
this.textBoxTargetDirectory.Location = new System.Drawing.Point(12, 333);
|
||||
this.textBoxTargetDirectory.Name = "textBoxTargetDirectory";
|
||||
this.helpProvider1.SetShowHelp(this.textBoxTargetDirectory, true);
|
||||
this.textBoxTargetDirectory.Size = new System.Drawing.Size(177, 20);
|
||||
this.textBoxTargetDirectory.TabIndex = 10;
|
||||
this.toolTip1.SetToolTip(this.textBoxTargetDirectory, "Target directory where the CDB will be stored");
|
||||
//
|
||||
// buttonSelect
|
||||
//
|
||||
this.helpProvider1.SetHelpString(this.buttonSelect, "Pick a target directory via folder browser");
|
||||
this.buttonSelect.Location = new System.Drawing.Point(195, 331);
|
||||
this.buttonSelect.Name = "buttonSelect";
|
||||
this.helpProvider1.SetShowHelp(this.buttonSelect, true);
|
||||
this.buttonSelect.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonSelect.TabIndex = 5;
|
||||
this.buttonSelect.Text = "Browse";
|
||||
this.toolTip1.SetToolTip(this.buttonSelect, "Pick a target directory via folder browser");
|
||||
this.buttonSelect.UseVisualStyleBackColor = true;
|
||||
this.buttonSelect.Click += new System.EventHandler(this.buttonSelect_Click);
|
||||
//
|
||||
// textBoxFileName
|
||||
//
|
||||
this.textBoxFileName.Location = new System.Drawing.Point(87, 360);
|
||||
this.textBoxFileName.Name = "textBoxFileName";
|
||||
this.textBoxFileName.Size = new System.Drawing.Size(148, 20);
|
||||
this.textBoxFileName.TabIndex = 6;
|
||||
this.textBoxFileName.TextChanged += new System.EventHandler(this.textBoxFileName_TextChanged);
|
||||
this.textBoxFileName.Leave += new System.EventHandler(this.textBoxFileName_Leave);
|
||||
//
|
||||
// labelFileName
|
||||
//
|
||||
this.labelFileName.AutoSize = true;
|
||||
this.labelFileName.Location = new System.Drawing.Point(12, 363);
|
||||
this.labelFileName.Name = "labelFileName";
|
||||
this.labelFileName.Size = new System.Drawing.Size(60, 13);
|
||||
this.labelFileName.TabIndex = 13;
|
||||
this.labelFileName.Text = "CDB Name";
|
||||
//
|
||||
// labelFileNameEnding
|
||||
//
|
||||
this.labelFileNameEnding.AutoSize = true;
|
||||
this.labelFileNameEnding.Location = new System.Drawing.Point(241, 363);
|
||||
this.labelFileNameEnding.Name = "labelFileNameEnding";
|
||||
this.labelFileNameEnding.Size = new System.Drawing.Size(29, 13);
|
||||
this.labelFileNameEnding.TabIndex = 14;
|
||||
this.labelFileNameEnding.Text = ".json";
|
||||
//
|
||||
// comboBoxCStandard
|
||||
//
|
||||
this.comboBoxCStandard.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxCStandard.FormattingEnabled = true;
|
||||
this.helpProvider1.SetHelpString(this.comboBoxCStandard, "Your Solution contains C Files. Please specify which C standard is to be used for" +
|
||||
" building.");
|
||||
this.comboBoxCStandard.Location = new System.Drawing.Point(87, 386);
|
||||
this.comboBoxCStandard.Name = "comboBoxCStandard";
|
||||
this.helpProvider1.SetShowHelp(this.comboBoxCStandard, true);
|
||||
this.comboBoxCStandard.Size = new System.Drawing.Size(183, 21);
|
||||
this.comboBoxCStandard.TabIndex = 7;
|
||||
this.toolTip1.SetToolTip(this.comboBoxCStandard, "Your Solution contains C Files. Please specify which C standard is to be used for" +
|
||||
" building.");
|
||||
//
|
||||
// labelCStandard
|
||||
//
|
||||
this.labelCStandard.AutoSize = true;
|
||||
this.labelCStandard.Location = new System.Drawing.Point(12, 389);
|
||||
this.labelCStandard.Name = "labelCStandard";
|
||||
this.labelCStandard.Size = new System.Drawing.Size(60, 13);
|
||||
this.labelCStandard.TabIndex = 16;
|
||||
this.labelCStandard.Text = "C Standard";
|
||||
//
|
||||
// treeViewProjects
|
||||
//
|
||||
this.treeViewProjects.CheckBoxes = true;
|
||||
this.treeViewProjects.Location = new System.Drawing.Point(12, 26);
|
||||
this.treeViewProjects.Name = "treeViewProjects";
|
||||
this.treeViewProjects.Size = new System.Drawing.Size(258, 216);
|
||||
this.treeViewProjects.TabIndex = 17;
|
||||
this.treeViewProjects.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ProjectCheckList_MouseUp);
|
||||
this.treeViewProjects.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeViewProjects_NodeCheckChanged);
|
||||
//
|
||||
// ProjectSetupWindow
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSize = true;
|
||||
this.ClientSize = new System.Drawing.Size(282, 443);
|
||||
this.Controls.Add(this.treeViewProjects);
|
||||
this.Controls.Add(this.labelCStandard);
|
||||
this.Controls.Add(this.comboBoxCStandard);
|
||||
this.Controls.Add(this.labelFileNameEnding);
|
||||
this.Controls.Add(this.labelFileName);
|
||||
this.Controls.Add(this.textBoxFileName);
|
||||
this.Controls.Add(this.buttonSelect);
|
||||
this.Controls.Add(this.textBoxTargetDirectory);
|
||||
this.Controls.Add(this.labelSelectProject);
|
||||
this.Controls.Add(this.buttonSelectAll);
|
||||
this.Controls.Add(this.labelPlatform);
|
||||
this.Controls.Add(this.labelConfiguration);
|
||||
this.Controls.Add(this.comboBoxPlatform);
|
||||
this.Controls.Add(this.comboBoxConfiguration);
|
||||
this.Controls.Add(this.buttonCreate);
|
||||
this.Controls.Add(this.buttonCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.helpProvider1.SetHelpString(this, "Create a CDB from the current C++ solution.");
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "ProjectSetupWindow";
|
||||
this.helpProvider1.SetShowHelp(this, true);
|
||||
this.Text = "Create Compilation Database";
|
||||
this.toolTip1.SetToolTip(this, "Create a CDB from the current C++ solution.");
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
private System.Windows.Forms.Button buttonCreate;
|
||||
private System.Windows.Forms.ComboBox comboBoxConfiguration;
|
||||
private System.Windows.Forms.ComboBox comboBoxPlatform;
|
||||
private System.Windows.Forms.Label labelConfiguration;
|
||||
private System.Windows.Forms.Label labelPlatform;
|
||||
private System.Windows.Forms.Button buttonSelectAll;
|
||||
private System.Windows.Forms.Label labelSelectProject;
|
||||
private System.Windows.Forms.FolderBrowserDialog folderBrowserTargetDirectory;
|
||||
private System.Windows.Forms.TextBox textBoxTargetDirectory;
|
||||
private System.Windows.Forms.Button buttonSelect;
|
||||
private System.Windows.Forms.TextBox textBoxFileName;
|
||||
private System.Windows.Forms.Label labelFileName;
|
||||
private System.Windows.Forms.Label labelFileNameEnding;
|
||||
private System.Windows.Forms.HelpProvider helpProvider1;
|
||||
private System.Windows.Forms.ToolTip toolTip1;
|
||||
private System.ComponentModel.BackgroundWorker backgroundWorker1;
|
||||
private System.Windows.Forms.ComboBox comboBoxCStandard;
|
||||
private System.Windows.Forms.Label labelCStandard;
|
||||
private System.Windows.Forms.TreeView treeViewProjects;
|
||||
}
|
||||
}
|
||||
+489
@@ -0,0 +1,489 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
public partial class ProjectSetupWindow : Form
|
||||
{
|
||||
public class SolutionProject
|
||||
{
|
||||
public string _name = "";
|
||||
public bool _include = false;
|
||||
|
||||
public SolutionProject(string name, bool include)
|
||||
{
|
||||
_name = name;
|
||||
_include = include;
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void OnCreateProject(List<EnvDTE.Project> projects, string configurationName, string platformName, string targetDir, string fileName, string cStandard);
|
||||
|
||||
// public List<SolutionProject> m_projects = new List<SolutionProject>();
|
||||
public Utility.SolutionUtility.SolutionStructure _projectStructure = new Utility.SolutionUtility.SolutionStructure();
|
||||
|
||||
public List<string> _configurations = new List<string>();
|
||||
public List<string> _platforms = new List<string>();
|
||||
|
||||
public OnCreateProject _onCreateProject = null;
|
||||
|
||||
public string _solutionDirectory = "";
|
||||
public string _solutionFileName = "foo";
|
||||
|
||||
public bool _containsCFiles = false;
|
||||
|
||||
private List<string> _cStandards = new List<string>() { "c1x", "gnu1x", "iso9899:201x", "c11", "gnu11", "iso9899:2011",
|
||||
"c9x", "gnu9x", "iso9899:199x", "c99", "gnu99", "iso9899:1999", "iso9899:199409", "c90", "gnu90", "iso9899:1990",
|
||||
"c89", "gnu89" };
|
||||
|
||||
public SolutionParser.CompilationDatabase _cdb = new SolutionParser.CompilationDatabase();
|
||||
|
||||
public ProjectSetupWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
UpdateGUI();
|
||||
|
||||
buttonCreate.Enabled = false;
|
||||
}
|
||||
|
||||
public void UpdateGUI()
|
||||
{
|
||||
Logging.Logging.LogInfo("Populating GUI");
|
||||
|
||||
InitProjectCheckList();
|
||||
InitComboBoxConfigurations();
|
||||
InitComboBoxPlatforms();
|
||||
InitTextBoxTargetDirectory();
|
||||
InitTextBoxFileName();
|
||||
InitComboBoxCStandard();
|
||||
}
|
||||
|
||||
private void InitComboBoxConfigurations()
|
||||
{
|
||||
Logging.Logging.LogInfo("Adding " + _configurations.Count.ToString() + " build configurations.");
|
||||
|
||||
foreach(string configuration in _configurations)
|
||||
{
|
||||
comboBoxConfiguration.Items.Add(configuration);
|
||||
}
|
||||
|
||||
if(comboBoxConfiguration.Items.Count > 0)
|
||||
{
|
||||
if(_cdb != null)
|
||||
{
|
||||
int index = comboBoxConfiguration.Items.IndexOf(_cdb.ConfigurationName);
|
||||
comboBoxConfiguration.SelectedIndex = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
comboBoxConfiguration.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitComboBoxPlatforms()
|
||||
{
|
||||
Logging.Logging.LogInfo("Adding " + _platforms.Count.ToString() + " target platforms.");
|
||||
|
||||
foreach (string platform in _platforms)
|
||||
{
|
||||
comboBoxPlatform.Items.Add(platform);
|
||||
}
|
||||
|
||||
if(comboBoxPlatform.Items.Count > 0)
|
||||
{
|
||||
if(_cdb != null)
|
||||
{
|
||||
int index = comboBoxPlatform.Items.IndexOf(_cdb.PlatformName);
|
||||
comboBoxPlatform.SelectedIndex = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
comboBoxPlatform.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitProjectCheckList()
|
||||
{
|
||||
// way to slow for large projects
|
||||
//if(_cdb != null)
|
||||
//{
|
||||
// _cdb.TryLoadData();
|
||||
//}
|
||||
|
||||
foreach(Utility.SolutionUtility.SolutionStructure.Node node in _projectStructure.Nodes)
|
||||
{
|
||||
if(node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.PROJECT)
|
||||
{
|
||||
TreeNode treeNode = new TreeNode(node.Name);
|
||||
node.UserData = treeNode;
|
||||
|
||||
if (_cdb != null && _cdb.IncludedProjects.Exists(item => item == treeNode.Text))
|
||||
{
|
||||
treeNode.Checked = true;
|
||||
}
|
||||
|
||||
treeViewProjects.Nodes.Add(treeNode);
|
||||
}
|
||||
else if(node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.FOLDER)
|
||||
{
|
||||
TreeNode[] subNodes = GetSubNodes(node as Utility.SolutionUtility.SolutionStructure.FolderNode);
|
||||
TreeNode treeNode = new TreeNode(node.Name, subNodes);
|
||||
node.UserData = treeNode;
|
||||
treeViewProjects.Nodes.Add(treeNode);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateCreateButtonEnabled();
|
||||
}
|
||||
|
||||
private TreeNode[] GetSubNodes(Utility.SolutionUtility.SolutionStructure.FolderNode folderNode)
|
||||
{
|
||||
List<TreeNode> result = new List<TreeNode>();
|
||||
|
||||
foreach(Utility.SolutionUtility.SolutionStructure.Node node in folderNode.SubNodes)
|
||||
{
|
||||
if(node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.PROJECT)
|
||||
{
|
||||
TreeNode treeNode = new TreeNode(node.Name);
|
||||
node.UserData = treeNode;
|
||||
result.Add(treeNode);
|
||||
}
|
||||
else if(node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.FOLDER)
|
||||
{
|
||||
TreeNode[] subNodes = GetSubNodes(node as Utility.SolutionUtility.SolutionStructure.FolderNode);
|
||||
TreeNode treeNode = new TreeNode(node.Name, subNodes);
|
||||
node.UserData = treeNode;
|
||||
result.Add(treeNode);
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
private void InitTextBoxTargetDirectory()
|
||||
{
|
||||
Logging.Logging.LogInfo("Setting default target directory: \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(_solutionDirectory) + "\"");
|
||||
|
||||
folderBrowserTargetDirectory.SelectedPath = _solutionDirectory;
|
||||
string rootDirectory = folderBrowserTargetDirectory.SelectedPath.ToString();
|
||||
textBoxTargetDirectory.Text = rootDirectory;
|
||||
}
|
||||
|
||||
private void InitTextBoxFileName()
|
||||
{
|
||||
Logging.Logging.LogInfo("Setting default file name: '" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(_solutionFileName) + "'");
|
||||
|
||||
if(_cdb == null)
|
||||
{
|
||||
textBoxFileName.Text = _solutionFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
textBoxFileName.Text = _cdb.Name;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitComboBoxCStandard()
|
||||
{
|
||||
if(_containsCFiles == false)
|
||||
{
|
||||
Logging.Logging.LogInfo("Hiding C Standard selection");
|
||||
|
||||
comboBoxCStandard.Hide();
|
||||
labelCStandard.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogInfo("Showing C Standard selection");
|
||||
|
||||
comboBoxCStandard.Show();
|
||||
labelCStandard.Show();
|
||||
|
||||
foreach(string standard in _cStandards)
|
||||
{
|
||||
comboBoxCStandard.Items.Add(standard);
|
||||
}
|
||||
|
||||
comboBoxCStandard.SelectedIndex = 3;
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Logging.Logging.LogInfo("Close button pressed. Aborting.");
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void buttonCreate_Click(object sender, EventArgs e)
|
||||
{
|
||||
OnCreate();
|
||||
}
|
||||
|
||||
private void OnCreate()
|
||||
{
|
||||
Logging.Logging.LogInfo("Create button pressed");
|
||||
|
||||
if (_onCreateProject != null)
|
||||
{
|
||||
string configurationName = "";
|
||||
string platformName = "";
|
||||
|
||||
configurationName = comboBoxConfiguration.SelectedItem as string;
|
||||
platformName = comboBoxPlatform.SelectedItem as string;
|
||||
|
||||
Logging.Logging.LogInfo("Configuration " + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(configurationName) + "|" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(platformName) + " was selected.");
|
||||
|
||||
string targetDir = textBoxTargetDirectory.Text;
|
||||
|
||||
if(Directory.Exists(targetDir) && CheckFileNameIsValid(textBoxFileName.Text))
|
||||
{
|
||||
if (CheckFileExists())
|
||||
{
|
||||
Logging.Logging.LogWarning("A file \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(targetDir + "\\" + textBoxFileName.Text) + "\" already exists.");
|
||||
|
||||
DialogResult result = MessageBox.Show("A file of the chosen name already exists. Do you want to replace it?", "Sourcetrail Plugin", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
||||
|
||||
if(result == DialogResult.No)
|
||||
{
|
||||
Logging.Logging.LogInfo("Aborting CDB creation and attempting to make file name unique.");
|
||||
MakeFileNameUnique();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string cStandard = "c11";
|
||||
if(_containsCFiles)
|
||||
{
|
||||
cStandard = comboBoxCStandard.SelectedItem as string;
|
||||
}
|
||||
|
||||
Logging.Logging.LogInfo("Setting C standard flag to " + cStandard);
|
||||
|
||||
_onCreateProject(GetTreeViewProjectItems(), configurationName, platformName, targetDir, textBoxFileName.Text, cStandard);
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Directory.Exists(targetDir) == false)
|
||||
{
|
||||
Logging.Logging.LogError("The target directory \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(targetDir) + "\" does not exist.");
|
||||
MessageBox.Show("The target directory does not exist.", "Sourcetrail Plugin", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
if (CheckFileNameIsValid(textBoxFileName.Text) == false)
|
||||
{
|
||||
Logging.Logging.LogError("The chosen file name \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(textBoxFileName.Text) + "\" is not valid. I'd almost dare to say it's invalid!");
|
||||
MessageBox.Show("The chosen file name is not valid.", "Sourcetrail Plugin", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogError("CDB create callback is not set. Cannot start creating CDB.");
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckFileNameIsValid(string fileName)
|
||||
{
|
||||
Regex badChars = new Regex("[" + Regex.Escape(new string(System.IO.Path.GetInvalidFileNameChars())) + "]");
|
||||
if(badChars.IsMatch(fileName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CheckFileExists()
|
||||
{
|
||||
string fileName = textBoxFileName.Text;
|
||||
string path = textBoxTargetDirectory.Text;
|
||||
string extension = labelFileNameEnding.Text;
|
||||
|
||||
return File.Exists(path + "\\" + fileName + extension);
|
||||
}
|
||||
|
||||
private List<EnvDTE.Project> GetTreeViewProjectItems()
|
||||
{
|
||||
List<EnvDTE.Project> solutionProjects = new List<EnvDTE.Project>();
|
||||
|
||||
// Stack<TreeNode> treeNodes = new Stack<TreeNode>();
|
||||
Stack<Utility.SolutionUtility.SolutionStructure.Node> nodeStack = new Stack<Utility.SolutionUtility.SolutionStructure.Node>();
|
||||
foreach(Utility.SolutionUtility.SolutionStructure.Node node in _projectStructure.Nodes)
|
||||
{
|
||||
nodeStack.Push(node);
|
||||
}
|
||||
|
||||
while(nodeStack.Count > 0)
|
||||
{
|
||||
Utility.SolutionUtility.SolutionStructure.Node node = nodeStack.Pop();
|
||||
|
||||
bool include = (node.UserData as TreeNode).Checked;
|
||||
|
||||
string name = node.Name;
|
||||
|
||||
if(node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.PROJECT
|
||||
&& (node.UserData as TreeNode).Checked == true)
|
||||
{
|
||||
solutionProjects.Add(node.Project);
|
||||
}
|
||||
else if(node.GetNodeType() == Utility.SolutionUtility.SolutionStructure.Node.NodeType.FOLDER)
|
||||
{
|
||||
Utility.SolutionUtility.SolutionStructure.FolderNode folderNode = node as Utility.SolutionUtility.SolutionStructure.FolderNode;
|
||||
foreach(Utility.SolutionUtility.SolutionStructure.Node subNode in folderNode.SubNodes)
|
||||
{
|
||||
nodeStack.Push(subNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return solutionProjects;
|
||||
}
|
||||
|
||||
private void ProjectCheckList_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void buttonSelectAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
bool select = false;
|
||||
|
||||
// if one or more items are unselected, select all
|
||||
// otherwise deselect all
|
||||
for (int i = 0; i < treeViewProjects.Nodes.Count; i++)
|
||||
{
|
||||
if (treeViewProjects.Nodes[i].Checked == false)
|
||||
{
|
||||
select = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < treeViewProjects.Nodes.Count; i++)
|
||||
{
|
||||
treeViewProjects.Nodes[i].Checked = select;
|
||||
}
|
||||
|
||||
UpdateCreateButtonEnabled();
|
||||
}
|
||||
|
||||
private void label1_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void buttonSelect_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(Directory.Exists(textBoxTargetDirectory.Text))
|
||||
{
|
||||
folderBrowserTargetDirectory.SelectedPath = textBoxTargetDirectory.Text;
|
||||
}
|
||||
|
||||
folderBrowserTargetDirectory.SelectedPath = textBoxTargetDirectory.Text;
|
||||
|
||||
DialogResult result = folderBrowserTargetDirectory.ShowDialog();
|
||||
|
||||
string selectedPath = folderBrowserTargetDirectory.SelectedPath;
|
||||
|
||||
textBoxTargetDirectory.Text = selectedPath;
|
||||
}
|
||||
|
||||
private void treeViewProjects_NodeCheckChanged(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
// treeViewProjects.AfterCheck -= treeViewProjects_NodeCheckChanged;
|
||||
|
||||
Stack<TreeNode> nodeStack = new Stack<TreeNode>();
|
||||
|
||||
foreach (TreeNode subNode in e.Node.Nodes)
|
||||
{
|
||||
nodeStack.Push(subNode);
|
||||
}
|
||||
|
||||
while (nodeStack.Count > 0)
|
||||
{
|
||||
var node = nodeStack.Pop();
|
||||
|
||||
node.Checked = e.Node.Checked;
|
||||
|
||||
//foreach (TreeNode subNode in node.Nodes)
|
||||
//{
|
||||
// nodeStack.Push(subNode);
|
||||
//}
|
||||
}
|
||||
|
||||
// treeViewProjects.AfterCheck += treeViewProjects_NodeCheckChanged;
|
||||
}
|
||||
|
||||
private void textBoxFileName_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void textBoxFileName_Leave(object sender, EventArgs e)
|
||||
{
|
||||
// MakeFileNameUnique();
|
||||
}
|
||||
|
||||
private void MakeFileNameUnique()
|
||||
{
|
||||
string fileName = textBoxFileName.Text;
|
||||
|
||||
int i = 0;
|
||||
while (CheckFileExists())
|
||||
{
|
||||
++i;
|
||||
textBoxFileName.Text = fileName + i.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProjectCheckList_ItemCheck(object sender, ItemCheckEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void ProjectCheckList_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void ProjectCheckList_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
UpdateCreateButtonEnabled();
|
||||
}
|
||||
|
||||
private void UpdateCreateButtonEnabled()
|
||||
{
|
||||
bool anythingChecked = false;
|
||||
|
||||
Stack<TreeNode> treeNodes = new Stack<TreeNode>();
|
||||
foreach(TreeNode node in treeViewProjects.Nodes)
|
||||
{
|
||||
treeNodes.Push(node);
|
||||
}
|
||||
|
||||
while(treeNodes.Count > 0)
|
||||
{
|
||||
TreeNode node = treeNodes.Pop();
|
||||
|
||||
if(node.Nodes.Count <= 0 && node.Checked == true)
|
||||
{
|
||||
anythingChecked = true;
|
||||
}
|
||||
|
||||
foreach(TreeNode subNode in node.Nodes)
|
||||
{
|
||||
treeNodes.Push(subNode);
|
||||
}
|
||||
}
|
||||
|
||||
buttonCreate.Enabled = anythingChecked;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1343
File diff suppressed because it is too large
Load Diff
Generated
+108
@@ -0,0 +1,108 @@
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
partial class WindowCDBReady
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WindowCDBReady));
|
||||
this.label_message = new System.Windows.Forms.Label();
|
||||
this.button_ok = new System.Windows.Forms.Button();
|
||||
this.button_import = new System.Windows.Forms.Button();
|
||||
this.button_open = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label_message
|
||||
//
|
||||
this.label_message.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.label_message.Location = new System.Drawing.Point(10, 9);
|
||||
this.label_message.MinimumSize = new System.Drawing.Size(290, 70);
|
||||
this.label_message.Name = "label_message";
|
||||
this.label_message.Size = new System.Drawing.Size(290, 70);
|
||||
this.label_message.TabIndex = 0;
|
||||
this.label_message.Text = "Message";
|
||||
//
|
||||
// button_ok
|
||||
//
|
||||
this.button_ok.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.button_ok.Location = new System.Drawing.Point(12, 87);
|
||||
this.button_ok.Name = "button_ok";
|
||||
this.button_ok.Size = new System.Drawing.Size(75, 23);
|
||||
this.button_ok.TabIndex = 1;
|
||||
this.button_ok.Text = "Finish";
|
||||
this.button_ok.UseVisualStyleBackColor = true;
|
||||
this.button_ok.Click += new System.EventHandler(this.button_ok_Click);
|
||||
//
|
||||
// button_import
|
||||
//
|
||||
this.button_import.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.button_import.Location = new System.Drawing.Point(227, 87);
|
||||
this.button_import.Name = "button_import";
|
||||
this.button_import.Size = new System.Drawing.Size(75, 23);
|
||||
this.button_import.TabIndex = 2;
|
||||
this.button_import.Text = "Import";
|
||||
this.button_import.UseVisualStyleBackColor = true;
|
||||
this.button_import.Click += new System.EventHandler(this.button_import_Click);
|
||||
//
|
||||
// button_open
|
||||
//
|
||||
this.button_open.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
|
||||
this.button_open.Location = new System.Drawing.Point(111, 87);
|
||||
this.button_open.Name = "button_open";
|
||||
this.button_open.Size = new System.Drawing.Size(92, 23);
|
||||
this.button_open.TabIndex = 3;
|
||||
this.button_open.Text = "Open Folder";
|
||||
this.button_open.UseVisualStyleBackColor = true;
|
||||
this.button_open.Click += new System.EventHandler(this.button_open_Click);
|
||||
//
|
||||
// WindowCDBReady
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(314, 122);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.button_open);
|
||||
this.Controls.Add(this.button_import);
|
||||
this.Controls.Add(this.button_ok);
|
||||
this.Controls.Add(this.label_message);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MinimumSize = new System.Drawing.Size(330, 160);
|
||||
this.Name = "WindowCDBReady";
|
||||
this.Text = "CDB Ready";
|
||||
this.Resize += new System.EventHandler(this.WindowCDBReady_Resize);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.Button button_ok;
|
||||
private System.Windows.Forms.Button button_import;
|
||||
private System.Windows.Forms.Button button_open;
|
||||
private System.Windows.Forms.Label label_message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
public partial class WindowCDBReady : Form
|
||||
{
|
||||
private string _message0 = "The CDB ";
|
||||
private string _message1 = " was created at directory ";
|
||||
private string _message2 = "Do you want to auto-import it in Sourcetrail now?";
|
||||
|
||||
private WindowCreateCDB.CreationResult _creationResult = new WindowCreateCDB.CreationResult();
|
||||
|
||||
public WindowCDBReady()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
label_message.AutoSize = false;
|
||||
label_message.MaximumSize = new Size((int)((float)MaximumSize.Width * 0.8f), 0);
|
||||
}
|
||||
|
||||
public void setData(WindowCreateCDB.CreationResult creationResult)
|
||||
{
|
||||
_creationResult = creationResult;
|
||||
|
||||
label_message.Text = _message0 + "'" + creationResult._cdbName + "'" + _message1 + "\"" + creationResult._cdbDirectory + "\".";
|
||||
label_message.Text += "\n" + _message2;
|
||||
}
|
||||
|
||||
private void button_ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void button_open_Click(object sender, EventArgs e)
|
||||
{
|
||||
Utility.SystemUtility.OpenWindowsExplorerAtDirectory(_creationResult._cdbDirectory);
|
||||
}
|
||||
|
||||
private void button_import_Click(object sender, EventArgs e)
|
||||
{
|
||||
string message = Utility.NetworkProtocolUtility.CreateCreateProjectMessage(_creationResult._cdbDirectory + "\\" + _creationResult._cdbName + ".json", _creationResult._headerDirectories);
|
||||
|
||||
Utility.AsynchronousClient.Send(message);
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void WindowCDBReady_Resize(object sender, EventArgs e)
|
||||
{
|
||||
label_message.MaximumSize = new Size((int)((float)MaximumSize.Width * 0.8f), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1328
File diff suppressed because it is too large
Load Diff
Generated
+84
@@ -0,0 +1,84 @@
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
partial class WindowCreateCDB
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WindowCreateCDB));
|
||||
this.progressBar = new System.Windows.Forms.ProgressBar();
|
||||
this.labelStatus = new System.Windows.Forms.Label();
|
||||
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// progressBar
|
||||
//
|
||||
this.progressBar.Location = new System.Drawing.Point(12, 12);
|
||||
this.progressBar.Name = "progressBar";
|
||||
this.progressBar.Size = new System.Drawing.Size(259, 23);
|
||||
this.progressBar.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
|
||||
this.progressBar.TabIndex = 0;
|
||||
//
|
||||
// labelStatus
|
||||
//
|
||||
this.labelStatus.AutoSize = true;
|
||||
this.labelStatus.Location = new System.Drawing.Point(13, 42);
|
||||
this.labelStatus.Name = "labelStatus";
|
||||
this.labelStatus.Size = new System.Drawing.Size(52, 13);
|
||||
this.labelStatus.TabIndex = 1;
|
||||
this.labelStatus.Text = "Waiting...";
|
||||
//
|
||||
// backgroundWorker1
|
||||
//
|
||||
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
|
||||
this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
|
||||
this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
|
||||
//
|
||||
// WindowCreateCDB
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(284, 63);
|
||||
this.Controls.Add(this.labelStatus);
|
||||
this.Controls.Add(this.progressBar);
|
||||
this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "WindowCreateCDB";
|
||||
this.Text = "Creating Compilation Data Base";
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.WindowCreateCDB_FormClosed);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ProgressBar progressBar;
|
||||
private System.Windows.Forms.Label labelStatus;
|
||||
private System.ComponentModel.BackgroundWorker backgroundWorker1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
public partial class WindowCreateCDB : Form
|
||||
{
|
||||
public struct CreationResult
|
||||
{
|
||||
public SolutionParser.CompilationDatabase _cdb;
|
||||
public string _cdbDirectory;
|
||||
public string _cdbName;
|
||||
public List<string> _headerDirectories;
|
||||
}
|
||||
|
||||
public delegate void OnFinishedCreatingCDB(CreationResult result);
|
||||
|
||||
private OnFinishedCreatingCDB _onFinishedCreateCDB = null;
|
||||
|
||||
private List<EnvDTE.Project> _projects = new List<EnvDTE.Project>();
|
||||
|
||||
private string _configurationName = "";
|
||||
private string _platformName = "";
|
||||
private string _targetDir = "";
|
||||
private string _fileName = "";
|
||||
private string _cStandard = "";
|
||||
private string _solutionDir = "";
|
||||
|
||||
private SolutionParser.CompilationDatabase _cdb = null;
|
||||
|
||||
CreationResult _result = new CreationResult();
|
||||
|
||||
private int _threadCount = 1;
|
||||
|
||||
private static object _lockObject = new object();
|
||||
private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();
|
||||
|
||||
public OnFinishedCreatingCDB CallbackOnFinishedCreatingCDB
|
||||
{
|
||||
get { return _onFinishedCreateCDB; }
|
||||
set { _onFinishedCreateCDB = value; }
|
||||
}
|
||||
|
||||
public List<EnvDTE.Project> Projects
|
||||
{
|
||||
get { return _projects; }
|
||||
set { _projects = value; }
|
||||
}
|
||||
|
||||
public string ConfigurationName
|
||||
{
|
||||
get { return _configurationName; }
|
||||
set { _configurationName = value; }
|
||||
}
|
||||
|
||||
public string PlatformName
|
||||
{
|
||||
get { return _platformName; }
|
||||
set { _platformName = value; }
|
||||
}
|
||||
|
||||
public string TargetDir
|
||||
{
|
||||
get { return _targetDir; }
|
||||
set { _targetDir = value; }
|
||||
}
|
||||
|
||||
public string FileName
|
||||
{
|
||||
get { return _fileName; }
|
||||
set { _fileName = value; }
|
||||
}
|
||||
|
||||
public string CStandard
|
||||
{
|
||||
get { return _cStandard; }
|
||||
set { _cStandard = value; }
|
||||
}
|
||||
|
||||
public int ThreadCount
|
||||
{
|
||||
get { return _threadCount; }
|
||||
set { _threadCount = value; }
|
||||
}
|
||||
|
||||
public string SolutionDir
|
||||
{
|
||||
get { return _solutionDir; }
|
||||
set { _solutionDir = value; }
|
||||
}
|
||||
|
||||
public SolutionParser.CompilationDatabase CDB
|
||||
{
|
||||
get { return _cdb; }
|
||||
set { _cdb = value; }
|
||||
}
|
||||
|
||||
|
||||
public WindowCreateCDB()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
progressBar.Maximum = 100;
|
||||
progressBar.Value = 0;
|
||||
|
||||
backgroundWorker1.WorkerReportsProgress = true;
|
||||
backgroundWorker1.WorkerSupportsCancellation = true;
|
||||
}
|
||||
|
||||
public void StartWorking()
|
||||
{
|
||||
// Show();
|
||||
|
||||
backgroundWorker1.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private CreationResult CreateCDB()
|
||||
{
|
||||
CreationResult result = new CreationResult();
|
||||
result._cdb = null;
|
||||
result._cdbDirectory = "";
|
||||
result._cdbName = "";
|
||||
result._headerDirectories = new List<string>();
|
||||
|
||||
SolutionParser.CompilationDatabase cdb = null;
|
||||
List<string> headerDirectories = new List<string>();
|
||||
|
||||
Logging.Logging.LogInfo("Starting to create CDB");
|
||||
|
||||
try
|
||||
{
|
||||
SolutionParser.SolutionParser._headerDirectories.Clear();
|
||||
|
||||
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
|
||||
|
||||
watch.Start();
|
||||
|
||||
cdb = CreateCommandObjects();
|
||||
|
||||
watch.Stop();
|
||||
|
||||
Logging.Logging.LogInfo("Finished, elapsed time: " + watch.ElapsedMilliseconds.ToString() + " ms");
|
||||
|
||||
headerDirectories = SolutionParser.SolutionParser._headerDirectories;
|
||||
|
||||
cdb.Name = _fileName;
|
||||
cdb.Directory = _targetDir;
|
||||
cdb.SourceProject = _solutionDir;
|
||||
cdb.LastUpdated = DateTime.Now;
|
||||
cdb.ConfigurationName = _configurationName;
|
||||
cdb.PlatformName = _platformName;
|
||||
|
||||
cdb.IncludedProjects = new List<string>();
|
||||
foreach (EnvDTE.Project p in _projects)
|
||||
{
|
||||
cdb.IncludedProjects.Add(p.Name);
|
||||
}
|
||||
|
||||
cdb.Clean();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to create CDB: " + e.Message);
|
||||
}
|
||||
|
||||
result._cdb = cdb;
|
||||
result._cdbDirectory = _targetDir;
|
||||
result._cdbName = _fileName;
|
||||
result._headerDirectories = headerDirectories;
|
||||
|
||||
Logging.Logging.LogInfo("Done creating CDB");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SolutionParser.CompilationDatabase CreateCommandObjects()
|
||||
{
|
||||
SolutionParser.CompilationDatabase cdb = new SolutionParser.CompilationDatabase();
|
||||
cdb.Directory = _targetDir;
|
||||
cdb.Name = _fileName;
|
||||
|
||||
File.WriteAllText(_targetDir + "\\" + _fileName + ".json", "");
|
||||
File.AppendAllText(_targetDir + "\\" + _fileName + ".json", "[\n");
|
||||
|
||||
// Mutex commandObjectMutex = new Mutex();
|
||||
|
||||
object lockObject = new object();
|
||||
object lockObject2 = new object();
|
||||
|
||||
Utility.QueuedFileWriter fileWriter = new Utility.QueuedFileWriter();
|
||||
fileWriter.FileName = _fileName + ".json";
|
||||
fileWriter.TargetDirectory = _targetDir;
|
||||
fileWriter.startWorking();
|
||||
|
||||
try
|
||||
{
|
||||
// parallel with tasks
|
||||
Multitasking.LimitedThreadsTaskScheduler scheduler = new Multitasking.LimitedThreadsTaskScheduler(_threadCount);
|
||||
TaskFactory factory = new TaskFactory(scheduler);
|
||||
|
||||
List<Task> tasks = new List<Task>();
|
||||
|
||||
int projectsProcessed = 0;
|
||||
foreach (EnvDTE.Project project in _projects)
|
||||
{
|
||||
string projectName = project.Name;
|
||||
|
||||
Logging.Logging.LogInfo("Scheduling " + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(projectName) + " for parsing.");
|
||||
|
||||
Task t = factory.StartNew(() =>
|
||||
{
|
||||
List<SolutionParser.CommandObject> commandObjects = SolutionParser.SolutionParser.CreateCommandObjects(project, _configurationName, _platformName, _cStandard);
|
||||
|
||||
lock (_lockObject)
|
||||
{
|
||||
projectsProcessed++;
|
||||
}
|
||||
|
||||
float relativProgress = (float)projectsProcessed / (float)_projects.Count;
|
||||
Logging.Logging.LogInfo("Processing project \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(project.Name) + "\"");
|
||||
backgroundWorker1.ReportProgress((int)(relativProgress * 100), "Processing project \"" + project.Name + "\"");
|
||||
|
||||
foreach (SolutionParser.CommandObject obj in commandObjects)
|
||||
{
|
||||
// cdb.AddOrUpdateCommandObject(obj, false); // since the data is written to file right away now, no need to store it
|
||||
// the cdb is however still needed to store some meta data later
|
||||
|
||||
fileWriter.pushMessage(obj.SerializeJSON() + ",");
|
||||
}
|
||||
});
|
||||
|
||||
tasks.Add(t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int threadCount = System.Diagnostics.Process.GetCurrentProcess().Threads.Count;
|
||||
|
||||
Task.WaitAll(tasks.ToArray());
|
||||
|
||||
fileWriter.stopWorking();
|
||||
|
||||
backgroundWorker1.ReportProgress(100, "Writing data to file. This might take several minutes...");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logging.Logging.LogError("Failed to create CDB: " + e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.AppendAllText(_targetDir + "\\" + _fileName + ".json", "\n]");
|
||||
}
|
||||
|
||||
return cdb;
|
||||
}
|
||||
|
||||
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
_result = CreateCDB();
|
||||
}
|
||||
|
||||
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
|
||||
{
|
||||
if(backgroundWorker1.CancellationPending == false)
|
||||
{
|
||||
progressBar.Value = e.ProgressPercentage;
|
||||
|
||||
labelStatus.Text = e.UserState as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
progressBar.Value = 0;
|
||||
|
||||
labelStatus.Text = "Cancelling...";
|
||||
}
|
||||
}
|
||||
|
||||
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if(e.Cancelled == false && e.Error == null /*&& progressBar.Value >= 100*/)
|
||||
{
|
||||
if (_onFinishedCreateCDB != null)
|
||||
{
|
||||
_onFinishedCreateCDB(_result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Logging.LogWarning("CDB creation was aborted by user");
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void WindowCreateCDB_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
backgroundWorker1.CancelAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1331
File diff suppressed because it is too large
Load Diff
Generated
+92
@@ -0,0 +1,92 @@
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
partial class WindowMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WindowMessage));
|
||||
this.buttonCancel = new System.Windows.Forms.Button();
|
||||
this.buttonOK = new System.Windows.Forms.Button();
|
||||
this.labelContent = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// buttonCancel
|
||||
//
|
||||
this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.buttonCancel.Location = new System.Drawing.Point(13, 78);
|
||||
this.buttonCancel.Name = "buttonCancel";
|
||||
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonCancel.TabIndex = 0;
|
||||
this.buttonCancel.Text = "Cancel";
|
||||
this.buttonCancel.UseVisualStyleBackColor = true;
|
||||
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
|
||||
//
|
||||
// buttonOK
|
||||
//
|
||||
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.buttonOK.Location = new System.Drawing.Point(257, 78);
|
||||
this.buttonOK.Name = "buttonOK";
|
||||
this.buttonOK.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonOK.TabIndex = 1;
|
||||
this.buttonOK.Text = "OK";
|
||||
this.buttonOK.UseVisualStyleBackColor = true;
|
||||
this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
|
||||
//
|
||||
// labelContent
|
||||
//
|
||||
this.labelContent.AutoSize = true;
|
||||
this.labelContent.Location = new System.Drawing.Point(13, 13);
|
||||
this.labelContent.MaximumSize = new System.Drawing.Size(300, 0);
|
||||
this.labelContent.Name = "labelContent";
|
||||
this.labelContent.Size = new System.Drawing.Size(44, 13);
|
||||
this.labelContent.TabIndex = 2;
|
||||
this.labelContent.Text = "Content";
|
||||
//
|
||||
// WindowMessage
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(344, 113);
|
||||
this.Controls.Add(this.labelContent);
|
||||
this.Controls.Add(this.buttonOK);
|
||||
this.Controls.Add(this.buttonCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "WindowMessage";
|
||||
this.Text = "Message";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button buttonCancel;
|
||||
private System.Windows.Forms.Button buttonOK;
|
||||
private System.Windows.Forms.Label labelContent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CoatiSoftware.SourcetrailPlugin.Wizard
|
||||
{
|
||||
public partial class WindowMessage : Form
|
||||
{
|
||||
private string _title = "Title";
|
||||
private string _message = "Message";
|
||||
|
||||
public delegate void Callback();
|
||||
|
||||
private Callback _onOK = null;
|
||||
private Callback _onCancel = null;
|
||||
|
||||
public string Title
|
||||
{
|
||||
get { return _title; }
|
||||
set { _title = value; }
|
||||
}
|
||||
|
||||
public string Message
|
||||
{
|
||||
get { return _message; }
|
||||
set { _message = value; }
|
||||
}
|
||||
|
||||
public Callback OnOK
|
||||
{
|
||||
get { return _onOK; }
|
||||
set { _onOK = value; }
|
||||
}
|
||||
|
||||
public Callback OnCancel
|
||||
{
|
||||
get { return _onCancel; }
|
||||
set { _onCancel = value; }
|
||||
}
|
||||
|
||||
public WindowMessage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void RefreshWindow()
|
||||
{
|
||||
Text = _title;
|
||||
labelContent.Text = _message;
|
||||
|
||||
if(_onCancel != null)
|
||||
{
|
||||
buttonCancel.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonCancel.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(_onCancel != null)
|
||||
{
|
||||
_onCancel();
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void buttonOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(_onOK != null)
|
||||
{
|
||||
_onOK();
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
|
||||
</packages>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
|
||||
<Metadata>
|
||||
<Identity Id="acf15780-03b5-440e-a41e-db79b7043fc2" Version="0.9.8" Language="en-US" Publisher="Coati Software OG" />
|
||||
<DisplayName>SourcetrailPlugin</DisplayName>
|
||||
<Description xml:space="preserve">This package allows Sourcetrail to communicate with Visual Studio and vice versa.</Description>
|
||||
<MoreInfo>http://www.sourcetrail.com/</MoreInfo>
|
||||
<ReleaseNotes>Creation of CDBs is in beta and may change in future versions</ReleaseNotes>
|
||||
<Icon>sourcetrail.ico</Icon>
|
||||
</Metadata>
|
||||
<Installation InstalledByMsi="false">
|
||||
<InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="11.0" />
|
||||
<InstallationTarget Version="[12.0,13.0)" Id="Microsoft.VisualStudio.Pro" />
|
||||
<InstallationTarget Version="[14.0,15.0)" Id="Microsoft.VisualStudio.Community" />
|
||||
</Installation>
|
||||
<Dependencies>
|
||||
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="4.5" />
|
||||
<Dependency Id="Microsoft.VisualStudio.MPF.11.0" DisplayName="Visual Studio MPF 11.0" d:Source="Installed" Version="11.0" />
|
||||
</Dependencies>
|
||||
<Assets>
|
||||
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
|
||||
</Assets>
|
||||
</PackageManifest>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
Vendored
BIN
Binary file not shown.
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net20/Newtonsoft.Json.dll
Vendored
BIN
Binary file not shown.
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net20/Newtonsoft.Json.xml
Vendored
+9793
File diff suppressed because it is too large
Load Diff
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net35/Newtonsoft.Json.dll
Vendored
BIN
Binary file not shown.
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net35/Newtonsoft.Json.xml
Vendored
+8922
File diff suppressed because it is too large
Load Diff
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net40/Newtonsoft.Json.dll
Vendored
BIN
Binary file not shown.
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net40/Newtonsoft.Json.xml
Vendored
+9229
File diff suppressed because it is too large
Load Diff
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net45/Newtonsoft.Json.dll
Vendored
BIN
Binary file not shown.
ide_plugins/vs/vs2015/SourcetrailPlugin/packages/Newtonsoft.Json.9.0.1/lib/net45/Newtonsoft.Json.xml
Vendored
+9229
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
+8756
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
+8409
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
+8756
File diff suppressed because it is too large
Load Diff
+116
@@ -0,0 +1,116 @@
|
||||
param($installPath, $toolsPath, $package, $project)
|
||||
|
||||
# open json.net splash page on package install
|
||||
# don't open if json.net is installed as a dependency
|
||||
|
||||
try
|
||||
{
|
||||
$url = "http://www.newtonsoft.com/json/install?version=" + $package.Version
|
||||
$dte2 = Get-Interface $dte ([EnvDTE80.DTE2])
|
||||
|
||||
if ($dte2.ActiveWindow.Caption -eq "Package Manager Console")
|
||||
{
|
||||
# user is installing from VS NuGet console
|
||||
# get reference to the window, the console host and the input history
|
||||
# show webpage if "install-package newtonsoft.json" was last input
|
||||
|
||||
$consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow])
|
||||
|
||||
$props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
$prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1
|
||||
if ($prop -eq $null) { return }
|
||||
|
||||
$hostInfo = $prop.GetValue($consoleWindow)
|
||||
if ($hostInfo -eq $null) { return }
|
||||
|
||||
$history = $hostInfo.WpfConsole.InputHistory.History
|
||||
|
||||
$lastCommand = $history | select -last 1
|
||||
|
||||
if ($lastCommand)
|
||||
{
|
||||
$lastCommand = $lastCommand.Trim().ToLower()
|
||||
if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("newtonsoft.json"))
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# user is installing from VS NuGet dialog
|
||||
# get reference to the window, then smart output console provider
|
||||
# show webpage if messages in buffered console contains "installing...newtonsoft.json" in last operation
|
||||
|
||||
$instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
$consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
if ($instanceField -eq $null -or $consoleField -eq $null) { return }
|
||||
|
||||
$instance = $instanceField.GetValue($null)
|
||||
|
||||
if ($instance -eq $null) { return }
|
||||
|
||||
$consoleProvider = $consoleField.GetValue($instance)
|
||||
if ($consoleProvider -eq $null) { return }
|
||||
|
||||
$console = $consoleProvider.CreateOutputConsole($false)
|
||||
|
||||
$messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor `
|
||||
[System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($messagesField -eq $null) { return }
|
||||
|
||||
$messages = $messagesField.GetValue($console)
|
||||
if ($messages -eq $null) { return }
|
||||
|
||||
$operations = $messages -split "=============================="
|
||||
|
||||
$lastOperation = $operations | select -last 1
|
||||
|
||||
if ($lastOperation)
|
||||
{
|
||||
$lastOperation = $lastOperation.ToLower()
|
||||
|
||||
$lines = $lastOperation -split "`r`n"
|
||||
|
||||
$installMatch = $lines | ? { $_.StartsWith("------- installing...newtonsoft.json ") } | select -first 1
|
||||
|
||||
if ($installMatch)
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
$pmPane = $dte2.ToolWindows.OutputWindow.OutputWindowPanes.Item("Package Manager")
|
||||
|
||||
$selection = $pmPane.TextDocument.Selection
|
||||
$selection.StartOfDocument($false)
|
||||
$selection.EndOfDocument($true)
|
||||
|
||||
if ($selection.Text.StartsWith("Attempting to gather dependencies information for package 'Newtonsoft.Json." + $package.Version + "'"))
|
||||
{
|
||||
# don't show on upgrade
|
||||
if (!$selection.Text.Contains("Removed package"))
|
||||
{
|
||||
$dte2.ItemOperations.Navigate($url) | Out-Null
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
# stop potential errors from bubbling up
|
||||
# worst case the splash page won't open
|
||||
}
|
||||
}
|
||||
|
||||
# still yolo
|
||||
Reference in New Issue
Block a user