logic: visual studio solution parsing
Can now parse visual studio solutions. VS Plugin can send a command, parsing is implemented in Coati. Some minor changes: added project file icon, added language check to vs plugin
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
#include "IDECommunicationController.h"
|
||||
|
||||
#include "component/controller/helper/NetworkProtocolHelper.h"
|
||||
#include "data/access/StorageAccess.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "data/location/TokenLocation.h"
|
||||
|
||||
#include "utility/messaging/type/MessageActivateTokenLocations.h"
|
||||
#include "utility/messaging/type/MessageActivateWindow.h"
|
||||
#include "utility/messaging/type/MessageLoadProject.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/messaging/type/MessageNewProject.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/solution/SolutionParserVisualStudio.h"
|
||||
|
||||
#include "settings/ProjectSettings.h"
|
||||
|
||||
IDECommunicationController::IDECommunicationController(StorageAccess* storageAccess)
|
||||
: m_storageAccess(storageAccess)
|
||||
@@ -21,30 +25,44 @@ IDECommunicationController::~IDECommunicationController()
|
||||
|
||||
void IDECommunicationController::handleIncomingMessage(const std::string& message)
|
||||
{
|
||||
LOG_WARNING_STREAM(<< message);
|
||||
NetworkProtocolHelper::MESSAGE_TYPE type = NetworkProtocolHelper::getMessageType(message);
|
||||
|
||||
NetworkProtocolHelper::NetworkMessage parsedMessage = NetworkProtocolHelper::parseMessage(message);
|
||||
|
||||
if (parsedMessage.valid)
|
||||
if (type == NetworkProtocolHelper::MESSAGE_TYPE::UNKNOWN)
|
||||
{
|
||||
const unsigned int cursorColumn = parsedMessage.column;
|
||||
LOG_ERROR_STREAM(<< "Invalid message type");
|
||||
}
|
||||
else if (type == NetworkProtocolHelper::MESSAGE_TYPE::SET_ACTIVE_TOKEN)
|
||||
{
|
||||
handleSetActiveTokenMessage(NetworkProtocolHelper::parseSetActiveTokenMessage(message));
|
||||
}
|
||||
else
|
||||
{
|
||||
handleCreateProjectMessage(NetworkProtocolHelper::parseCreateProjectMessage(message));
|
||||
}
|
||||
}
|
||||
|
||||
void IDECommunicationController::handleSetActiveTokenMessage(const NetworkProtocolHelper::SetActiveTokenMessage& message)
|
||||
{
|
||||
if (message.valid)
|
||||
{
|
||||
const unsigned int cursorColumn = message.column;
|
||||
|
||||
std::shared_ptr<TokenLocationFile> tokenLocationFile = m_storageAccess->getTokenLocationsForLinesInFile(
|
||||
parsedMessage.fileLocation, parsedMessage.row, parsedMessage.row
|
||||
);
|
||||
message.fileLocation, message.row, message.row
|
||||
);
|
||||
|
||||
std::vector<Id> selectedLocationIds;
|
||||
tokenLocationFile->forEachStartTokenLocation(
|
||||
[&](TokenLocation* startLocation)
|
||||
{
|
||||
TokenLocation* endLocation = startLocation->getEndTokenLocation();
|
||||
{
|
||||
TokenLocation* endLocation = startLocation->getEndTokenLocation();
|
||||
|
||||
if (!startLocation->isScopeTokenLocation() &&
|
||||
startLocation->getColumnNumber() <= cursorColumn && endLocation->getColumnNumber() + 1 >= cursorColumn)
|
||||
{
|
||||
selectedLocationIds.push_back(startLocation->getId());
|
||||
}
|
||||
if (!startLocation->isScopeTokenLocation() &&
|
||||
startLocation->getColumnNumber() <= cursorColumn && endLocation->getColumnNumber() + 1 >= cursorColumn)
|
||||
{
|
||||
selectedLocationIds.push_back(startLocation->getId());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (selectedLocationIds.size() > 0)
|
||||
@@ -57,7 +75,53 @@ void IDECommunicationController::handleIncomingMessage(const std::string& messag
|
||||
{
|
||||
MessageStatus(
|
||||
"Activating a source location from external failed. No symbol(s) have been found at the selected location."
|
||||
).dispatch();
|
||||
).dispatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IDECommunicationController::handleCreateProjectMessage(const NetworkProtocolHelper::CreateProjectMessage& message)
|
||||
{
|
||||
if (message.valid)
|
||||
{
|
||||
if (message.ideId == NetworkProtocolHelper::CreateProjectMessage::IDE_ID::VS)
|
||||
{
|
||||
SolutionParserVisualStudio parser;
|
||||
|
||||
parser.openSolutionFile(message.solutionFileLocation);
|
||||
std::vector<std::string> includePaths = parser.getIncludePaths();
|
||||
std::vector<std::string> projectItems = parser.getProjectItems();
|
||||
|
||||
std::vector<FilePath> projectFPs;
|
||||
std::vector<FilePath> includeFPs;
|
||||
|
||||
for (unsigned int i = 0; i < projectItems.size(); i++)
|
||||
{
|
||||
projectFPs.push_back(FilePath(projectItems[i]));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < includePaths.size(); i++)
|
||||
{
|
||||
includeFPs.push_back(FilePath(includePaths[i]));
|
||||
}
|
||||
|
||||
/*ProjectSettings* projSettings = ProjectSettings::getInstance().get();
|
||||
projSettings->clear();
|
||||
|
||||
projSettings->setLanguage("c++");
|
||||
projSettings->setStandard("11");
|
||||
|
||||
projSettings->setSourcePaths(projectFPs);
|
||||
projSettings->setHeaderSearchPaths(includeFPs);
|
||||
|
||||
std::string filePath = parser.getSolutionPath() + parser.getSolutionName() + ".coatiproject";
|
||||
projSettings->save(filePath);*/
|
||||
|
||||
MessageNewProject(parser.getSolutionName(), parser.getSolutionPath(), projectItems, includePaths).dispatch();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Unable to parse provided solution, unknown format");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "component/controller/Controller.h"
|
||||
|
||||
#include "component/controller/helper/NetworkProtocolHelper.h"
|
||||
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageMoveIDECursor.h"
|
||||
|
||||
@@ -21,6 +23,9 @@ public:
|
||||
void handleIncomingMessage(const std::string& message);
|
||||
|
||||
private:
|
||||
void handleSetActiveTokenMessage(const NetworkProtocolHelper::SetActiveTokenMessage& message);
|
||||
void handleCreateProjectMessage(const NetworkProtocolHelper::CreateProjectMessage& message);
|
||||
|
||||
virtual void handleMessage(MessageMoveIDECursor* message);
|
||||
virtual void sendMessage(const std::string& message) const = 0;
|
||||
|
||||
|
||||
@@ -3,38 +3,119 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
std::string NetworkProtocolHelper::m_divider = ">>";
|
||||
std::string NetworkProtocolHelper::m_setActiveTokenPrefix = "setActiveToken";
|
||||
std::string NetworkProtocolHelper::m_moveCursorPrefix = "moveCursor";
|
||||
std::string NetworkProtocolHelper::m_endOfMessageToken = "<EOM>";
|
||||
std::string NetworkProtocolHelper::m_createProjectPrefix = "createProject";
|
||||
|
||||
NetworkProtocolHelper::NetworkMessage NetworkProtocolHelper::parseMessage(const std::string& message)
|
||||
NetworkProtocolHelper::MESSAGE_TYPE NetworkProtocolHelper::getMessageType(const std::string& message)
|
||||
{
|
||||
NetworkMessage networkMessage;
|
||||
|
||||
size_t pos = message.find(m_setActiveTokenPrefix);
|
||||
std::vector<std::string> subMessages = divideMessage(message);
|
||||
|
||||
if(pos != std::string::npos)
|
||||
if (subMessages.size() > 0)
|
||||
{
|
||||
std::string tmpMessage = "";
|
||||
getSubstringAfterString(message, m_divider, tmpMessage); // just get rid of message type
|
||||
tmpMessage = removeEndOfMessageToken(tmpMessage);
|
||||
if (subMessages[0] == m_setActiveTokenPrefix)
|
||||
{
|
||||
return MESSAGE_TYPE::SET_ACTIVE_TOKEN;
|
||||
}
|
||||
else if (subMessages[0] == m_createProjectPrefix)
|
||||
{
|
||||
return MESSAGE_TYPE::CREATE_PROJECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MESSAGE_TYPE::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return MESSAGE_TYPE::UNKNOWN;
|
||||
}
|
||||
|
||||
std::string fileLocation = getSubstringAfterString(tmpMessage, m_divider, tmpMessage);
|
||||
std::string row = getSubstringAfterString(tmpMessage, m_divider, tmpMessage);
|
||||
std::string column = tmpMessage; // there should be nothing left in the message but the column number
|
||||
NetworkProtocolHelper::SetActiveTokenMessage NetworkProtocolHelper::parseSetActiveTokenMessage(const std::string& message)
|
||||
{
|
||||
std::vector<std::string> subMessages = divideMessage(message);
|
||||
|
||||
if(
|
||||
fileLocation.length() > 0
|
||||
&& row.length() > 0
|
||||
&& column.length() > 0
|
||||
&& isDigits(row)
|
||||
&& isDigits(column)
|
||||
){
|
||||
networkMessage.fileLocation = fileLocation;
|
||||
networkMessage.row = std::stoi(row);
|
||||
networkMessage.column = std::stoi(column);
|
||||
networkMessage.valid = true;
|
||||
SetActiveTokenMessage networkMessage;
|
||||
|
||||
if (subMessages.size() > 0)
|
||||
{
|
||||
if (subMessages[0] == m_setActiveTokenPrefix)
|
||||
{
|
||||
if (subMessages.size() != 5)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse setActiveToken message, invalid token count");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fileLocation = subMessages[1];
|
||||
std::string row = subMessages[2];
|
||||
std::string column = subMessages[3];
|
||||
|
||||
if(
|
||||
fileLocation.length() > 0
|
||||
&& row.length() > 0
|
||||
&& column.length() > 0
|
||||
&& isDigits(row)
|
||||
&& isDigits(column)
|
||||
){
|
||||
networkMessage.fileLocation = fileLocation;
|
||||
networkMessage.row = std::stoi(row);
|
||||
networkMessage.column = std::stoi(column);
|
||||
networkMessage.valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token");
|
||||
}
|
||||
}
|
||||
|
||||
return networkMessage;
|
||||
}
|
||||
|
||||
NetworkProtocolHelper::CreateProjectMessage NetworkProtocolHelper::parseCreateProjectMessage(const std::string& message)
|
||||
{
|
||||
std::vector<std::string> subMessages = divideMessage(message);
|
||||
|
||||
NetworkProtocolHelper::CreateProjectMessage networkMessage;
|
||||
|
||||
if (subMessages.size() > 0)
|
||||
{
|
||||
if (subMessages[0] == m_createProjectPrefix)
|
||||
{
|
||||
if (subMessages.size() != 4)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse createProject message, invalid token count");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fileLocation = subMessages[1];
|
||||
std::string ideId = subMessages[2];
|
||||
if (fileLocation.length() > 0
|
||||
&& ideId.length() > 0)
|
||||
{
|
||||
networkMessage.solutionFileLocation = fileLocation;
|
||||
|
||||
if (ideId == "vs")
|
||||
{
|
||||
networkMessage.ideId = CreateProjectMessage::IDE_ID::VS;
|
||||
}
|
||||
else
|
||||
{
|
||||
networkMessage.ideId = CreateProjectMessage::IDE_ID::UNKNOWN;
|
||||
}
|
||||
|
||||
networkMessage.valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +138,36 @@ std::string NetworkProtocolHelper::buildMessage(const std::string& fileLocation,
|
||||
return messageStream.str();
|
||||
}
|
||||
|
||||
std::vector<std::string> NetworkProtocolHelper::divideMessage(const std::string& message)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
std::string msg = message;
|
||||
size_t pos = msg.find(m_divider);
|
||||
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
std::string subMessage = msg.substr(0, pos);
|
||||
result.push_back(subMessage);
|
||||
msg = msg.substr(pos + m_divider.size());
|
||||
pos = msg.find(m_divider);
|
||||
}
|
||||
|
||||
if (msg.size() > 0)
|
||||
{
|
||||
pos = msg.find(m_endOfMessageToken);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string subMessage = msg.substr(0, pos);
|
||||
result.push_back(subMessage);
|
||||
msg = msg.substr(pos);
|
||||
result.push_back(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string NetworkProtocolHelper::removeEndOfMessageToken(const std::string& message)
|
||||
{
|
||||
size_t pos = message.find(m_endOfMessageToken);
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
#define NETWORK_PROTOCOL_HELPER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class NetworkProtocolHelper
|
||||
{
|
||||
public:
|
||||
struct NetworkMessage
|
||||
struct SetActiveTokenMessage
|
||||
{
|
||||
public:
|
||||
NetworkMessage()
|
||||
SetActiveTokenMessage()
|
||||
: fileLocation("")
|
||||
, row(0)
|
||||
, column(0)
|
||||
@@ -22,10 +23,43 @@ public:
|
||||
bool valid;
|
||||
};
|
||||
|
||||
static NetworkMessage parseMessage(const std::string& message);
|
||||
struct CreateProjectMessage
|
||||
{
|
||||
public:
|
||||
CreateProjectMessage()
|
||||
: solutionFileLocation("")
|
||||
, ideId(IDE_ID::UNKNOWN)
|
||||
, valid(false)
|
||||
{}
|
||||
|
||||
enum IDE_ID
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
VS
|
||||
};
|
||||
|
||||
std::string solutionFileLocation;
|
||||
IDE_ID ideId;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
enum MESSAGE_TYPE
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
SET_ACTIVE_TOKEN,
|
||||
CREATE_PROJECT
|
||||
};
|
||||
|
||||
static MESSAGE_TYPE getMessageType(const std::string& message);
|
||||
|
||||
static SetActiveTokenMessage parseSetActiveTokenMessage(const std::string& message);
|
||||
static CreateProjectMessage parseCreateProjectMessage(const std::string& message);
|
||||
|
||||
static std::string buildMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column);
|
||||
|
||||
private:
|
||||
static std::vector<std::string> divideMessage(const std::string& message);
|
||||
|
||||
static std::string removeEndOfMessageToken(const std::string& message);
|
||||
|
||||
static std::string getSubstringAfterString(const std::string& message, const std::string& searchString, std::string& subMessage);
|
||||
@@ -35,6 +69,7 @@ private:
|
||||
static std::string m_setActiveTokenPrefix;
|
||||
static std::string m_moveCursorPrefix;
|
||||
static std::string m_endOfMessageToken;
|
||||
static std::string m_createProjectPrefix;
|
||||
};
|
||||
|
||||
#endif // NETWORK_PROTOCOL_HELPER_H
|
||||
Reference in New Issue
Block a user