src: removed query syntax

This change removes the query syntax from the QtSmartSearchbox and all its classes. Now it only autocompletes to one
single Token, but the UI functionality for composing a query of multiple elements is still left for later use. The struct
SearchMatch is now used in the whole pipeline for passing search results back and forth.
This commit is contained in:
Eberhard Graether
2015-09-02 11:52:07 +02:00
parent 9bcf7d2f0f
commit 1b445d4c3a
38 changed files with 247 additions and 1696 deletions
+1 -1
View File
@@ -110,7 +110,7 @@ void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewIt
}
else
{
color = QColor(scheme->getQueryNodeTypeColor(QueryNode::QUERYNODETYPE_COMMAND).c_str());
color = QColor(scheme->getSearchTypeColor(SearchMatch::getSearchTypeName(SearchMatch::SEARCH_COMMAND)).c_str());
}
+1 -1
View File
@@ -57,7 +57,7 @@ QSize QtSearchBar::sizeHint() const
return QSize(400, 100);
}
void QtSearchBar::setMatches(const std::deque<SearchMatch>& matches)
void QtSearchBar::setMatches(const std::vector<SearchMatch>& matches)
{
m_searchBox->setMatches(matches);
}
+1 -1
View File
@@ -22,7 +22,7 @@ public:
virtual QSize sizeHint() const;
void setMatches(const std::deque<SearchMatch>& matches);
void setMatches(const std::vector<SearchMatch>& matches);
void setFocus();
void setAutocompletionList(const std::vector<SearchMatch>& autocompletionList);
+95 -68
View File
@@ -10,13 +10,13 @@
#include "utility/messaging/type/MessageSearch.h"
#include "utility/messaging/type/MessageSearchAutocomplete.h"
#include "utility/text/TextAccess.h"
#include "utility/utility.h"
#include "utility/utilityString.h"
#include "data/query/QueryTree.h"
#include "qt/element/QtAutocompletionList.h"
#include "settings/ColorScheme.h"
QtQueryElement::QtQueryElement(const QString& text, QWidget* parent)
QtSearchElement::QtSearchElement(const QString& text, QWidget* parent)
: QPushButton(text, parent)
{
show();
@@ -24,7 +24,7 @@ QtQueryElement::QtQueryElement(const QString& text, QWidget* parent)
connect(this, SIGNAL(clicked(bool)), this, SLOT(onChecked(bool)));
}
void QtQueryElement::onChecked(bool)
void QtSearchElement::onChecked(bool)
{
emit wasChecked(this);
}
@@ -34,13 +34,16 @@ void QtSmartSearchBox::search()
{
editTextToElement();
LOG_INFO_STREAM(<< "Search query: " << SearchMatch::searchMatchDequeToString(m_tokens) << text().toStdString());
std::vector<SearchMatch> matches = utility::toVector(m_matches);
MessageSearch(m_tokens).dispatch();
LOG_INFO_STREAM(<< "Search query: " << SearchMatch::searchMatchesToString(matches) << text().toStdString());
MessageSearch(matches).dispatch();
}
QtSmartSearchBox::QtSmartSearchBox(QWidget* parent)
: QLineEdit(parent)
, m_allowMultipleElements(false)
, m_allowTextChange(false)
, m_cursorIndex(0)
, m_shiftKeyDown(false)
@@ -82,16 +85,20 @@ void QtSmartSearchBox::setAutocompletionList(const std::vector<SearchMatch>& aut
}
}
void QtSmartSearchBox::setMatches(const std::deque<SearchMatch>& matches)
void QtSmartSearchBox::setMatches(const std::vector<SearchMatch>& matches)
{
if (SearchMatch::searchMatchDequeToString(matches) == SearchMatch::searchMatchDequeToString(m_tokens))
if (SearchMatch::searchMatchesToString(matches) == SearchMatch::searchMatchesToString(utility::toVector(m_matches)))
{
return;
}
clearLineEdit();
m_tokens = matches;
m_cursorIndex = m_tokens.size();
m_matches.clear();
m_matches.insert(m_matches.begin(), matches.begin(), matches.end());
m_cursorIndex = m_matches.size();
updateElements();
}
@@ -111,9 +118,9 @@ bool QtSmartSearchBox::event(QEvent *event)
{
if (completer()->popup()->isVisible())
{
searchMatchToToken(m_highlightedMatch);
addMatchAndUpdate(m_highlightedMatch);
}
else
else if (m_allowMultipleElements)
{
requestAutoCompletions();
}
@@ -212,7 +219,7 @@ void QtSmartSearchBox::keyPressEvent(QKeyEvent* event)
{
if (completer()->popup()->isVisible())
{
searchMatchToToken(m_highlightedMatch);
addMatchAndUpdate(m_highlightedMatch);
}
else if (!editTextToElement())
{
@@ -287,6 +294,7 @@ void QtSmartSearchBox::keyPressEvent(QKeyEvent* event)
{
setEditText(text() + QApplication::clipboard()->text());
onTextEdited(text());
m_allowTextChange = false;
return;
}
@@ -302,7 +310,7 @@ void QtSmartSearchBox::mouseMoveEvent(QMouseEvent* event)
{
QLineEdit::mouseMoveEvent(event);
if (!m_mousePressed)
if (!m_mousePressed || !m_elements.size())
{
return;
}
@@ -369,27 +377,33 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
m_allowTextChange = true;
deleteSelectedElements();
bool tokensChanged = false;
bool matchesChanged = false;
SearchMatch token;
std::deque<SearchMatch> tokens = SearchMatch::stringDequeToSearchMatchDeque(QueryTree::tokenizeQuery(text.toStdString()));
SearchMatch match;
std::deque<SearchMatch> matches = getMatchesForInput(text.toStdString());
while (tokens.size())
while (matches.size())
{
token = tokens.front();
tokens.pop_front();
match = matches.front();
matches.pop_front();
if (tokens.size() || token.queryNodeType != QueryNode::QUERYNODETYPE_NONE)
if (matches.size() || match.isValid())
{
matchToToken(token);
token.decodeFromQuery("");
tokensChanged = true;
addMatch(match);
match = SearchMatch();
matchesChanged = true;
}
}
if (tokensChanged)
if (match.fullName.size() && !m_allowMultipleElements)
{
setEditText(QString::fromStdString(token.fullName));
clearMatches();
matchesChanged = true;
}
if (matchesChanged)
{
setEditText(QString::fromStdString(match.fullName));
updateElements();
}
else
@@ -397,7 +411,7 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
layoutElements();
}
if (token.fullName.size() || m_elements.size())
if (match.fullName.size() || m_elements.size())
{
requestAutoCompletions();
}
@@ -426,7 +440,7 @@ void QtSmartSearchBox::onAutocompletionHighlighted(const SearchMatch& match)
void QtSmartSearchBox::onAutocompletionActivated(const SearchMatch& match)
{
searchMatchToToken(match);
addMatchAndUpdate(match);
if (match.fullName.size())
{
@@ -434,7 +448,7 @@ void QtSmartSearchBox::onAutocompletionActivated(const SearchMatch& match)
}
}
void QtSmartSearchBox::onElementSelected(QtQueryElement* element)
void QtSmartSearchBox::onElementSelected(QtSearchElement* element)
{
if (!hasSelectedElements() && !m_shiftKeyDown)
{
@@ -496,39 +510,51 @@ void QtSmartSearchBox::moveCursorTo(int target)
}
void QtSmartSearchBox::matchToToken(const SearchMatch& match)
void QtSmartSearchBox::addMatch(const SearchMatch& match)
{
if(!match.fullName.size())
if (!match.fullName.size())
{
return;
}
const SearchMatch* matchPtr = &match;
if(completer()->popup()->isVisible())
if (completer()->popup()->isVisible())
{
const SearchMatch* m = dynamic_cast<QtAutocompletionList*>(completer())->getSearchMatchAt(0);
if (m && utility::equalsCaseInsensitive(match.fullName, m->fullName))
const SearchMatch* mPtr = dynamic_cast<QtAutocompletionList*>(completer())->getSearchMatchAt(0);
if (mPtr && utility::equalsCaseInsensitive(match.fullName, mPtr->fullName))
{
matchPtr = m;
matchPtr = mPtr;
}
}
m_tokens.insert(m_tokens.begin() + m_cursorIndex, *matchPtr);
if (!m_allowMultipleElements)
{
clearMatches();
}
m_matches.insert(m_matches.begin() + m_cursorIndex, *matchPtr);
m_cursorIndex++;
}
void QtSmartSearchBox::searchMatchToToken(const SearchMatch& match)
void QtSmartSearchBox::addMatchAndUpdate(const SearchMatch& match)
{
if (match.fullName.size())
{
m_oldText.clear();
clearLineEdit();
matchToToken(match);
addMatch(match);
updateElements();
}
}
void QtSmartSearchBox::clearMatches()
{
m_matches.clear();
m_cursorIndex = 0;
}
void QtSmartSearchBox::setEditText(const QString& text)
{
m_allowTextChange = true;
@@ -539,7 +565,7 @@ bool QtSmartSearchBox::editTextToElement()
{
if (text().size())
{
matchToToken(SearchMatch(text().toStdString()));
addMatch(SearchMatch(text().toStdString()));
clearLineEdit();
updateElements();
@@ -549,7 +575,7 @@ bool QtSmartSearchBox::editTextToElement()
return false;
}
void QtSmartSearchBox::editElement(QtQueryElement* element)
void QtSmartSearchBox::editElement(QtSearchElement* element)
{
for (int i = m_elements.size() - 1; i >= 0; i--)
{
@@ -560,10 +586,10 @@ void QtSmartSearchBox::editElement(QtQueryElement* element)
}
}
std::string token = m_tokens[m_cursorIndex].fullName;
m_tokens.erase(m_tokens.begin() + m_cursorIndex);
std::string name = m_matches[m_cursorIndex].fullName;
m_matches.erase(m_matches.begin() + m_cursorIndex);
setEditText(QString::fromStdString(token));
setEditText(QString::fromStdString(name));
updateElements();
requestAutoCompletions();
@@ -577,29 +603,30 @@ void QtSmartSearchBox::updateElements()
std::string textColor = scheme->getColor("search/field/text");
for (const SearchMatch& token : m_tokens)
for (const SearchMatch& match : m_matches)
{
std::string name = token.fullName;
std::string name = match.fullName;
name = utility::replace(name, "&", "&&");
std::shared_ptr<QtQueryElement> element = std::make_shared<QtQueryElement>(QString::fromStdString(name), this);
std::shared_ptr<QtSearchElement> element = std::make_shared<QtSearchElement>(QString::fromStdString(name), this);
m_elements.push_back(element);
std::string color;
std::string hoverColor;
if (token.queryNodeType == QueryNode::QUERYNODETYPE_TOKEN)
if (match.searchType == SearchMatch::SEARCH_TOKEN)
{
element->setObjectName(QString::fromStdString("search_element_" + token.getNodeTypeAsString()));
color = scheme->getNodeTypeColor(token.nodeType);
hoverColor = scheme->getNodeTypeColor(token.nodeType, "hover");
element->setObjectName(QString::fromStdString("search_element_" + match.getNodeTypeAsString()));
color = scheme->getNodeTypeColor(match.nodeType);
hoverColor = scheme->getNodeTypeColor(match.nodeType, "hover");
}
else
{
element->setObjectName(QString::fromStdString("search_element_" + QueryTree::getTokenTypeName(token.queryNodeType)));
color = scheme->getQueryNodeTypeColor(token.queryNodeType);
hoverColor = scheme->getQueryNodeTypeColor(token.queryNodeType, "hover");
std::string typeName = match.getSearchTypeName();
element->setObjectName(QString::fromStdString("search_element_" + typeName));
color = scheme->getSearchTypeColor(typeName);
hoverColor = scheme->getSearchTypeColor(typeName, "hover");
}
std::stringstream css;
@@ -608,7 +635,7 @@ void QtSmartSearchBox::updateElements()
element->setStyleSheet(css.str().c_str());
connect(element.get(), SIGNAL(wasChecked(QtQueryElement*)), this, SLOT(onElementSelected(QtQueryElement*)));
connect(element.get(), SIGNAL(wasChecked(QtSearchElement*)), this, SLOT(onElementSelected(QtSearchElement*)));
}
updatePlaceholder();
@@ -649,7 +676,7 @@ void QtSmartSearchBox::layoutElements()
if (i < m_elements.size())
{
QtQueryElement* button = m_elements[i].get();
QtSearchElement* button = m_elements[i].get();
if (button->isChecked() && !highlightBegin)
{
@@ -674,7 +701,7 @@ void QtSmartSearchBox::layoutElements()
for (size_t i = 0; i < elementX.size(); i++)
{
QtQueryElement* button = m_elements[i].get();
QtSearchElement* button = m_elements[i].get();
QSize size = button->minimumSizeHint();
int y = (rect().height() - size.height()) / 2.0;
button->setGeometry(elementX[i] + offsetX, y, size.width(), size.height());
@@ -695,7 +722,7 @@ void QtSmartSearchBox::layoutElements()
bool QtSmartSearchBox::hasSelectedElements() const
{
for (const std::shared_ptr<QtQueryElement> element : m_elements)
for (const std::shared_ptr<QtSearchElement> element : m_elements)
{
if (element->isChecked())
{
@@ -712,7 +739,7 @@ std::string QtSmartSearchBox::getSelectedString() const
{
if (m_elements[i]->isChecked())
{
str += m_tokens[i].encodeForQuery();
str += m_matches[i].fullName;
}
}
return str;
@@ -720,7 +747,7 @@ std::string QtSmartSearchBox::getSelectedString() const
void QtSmartSearchBox::selectAllElementsWith(bool selected)
{
for (const std::shared_ptr<QtQueryElement> element : m_elements)
for (const std::shared_ptr<QtSearchElement> element : m_elements)
{
element->setChecked(selected);
}
@@ -763,7 +790,7 @@ void QtSmartSearchBox::deleteSelectedElements()
{
if (m_elements[i - 1]->isChecked())
{
m_tokens.erase(m_tokens.begin() + (i - 1));
m_matches.erase(m_matches.begin() + (i - 1));
if ((i - 1) < m_cursorIndex)
{
@@ -795,17 +822,17 @@ void QtSmartSearchBox::clearLineEdit()
void QtSmartSearchBox::requestAutoCompletions() const
{
std::string query;
for (size_t i = 0; i < m_tokens.size() && i < m_cursorIndex; i++)
{
query += m_tokens[i].encodeForQuery();
}
MessageSearchAutocomplete(query, text().toStdString()).dispatch();
MessageSearchAutocomplete("", text().toStdString()).dispatch();
}
void QtSmartSearchBox::hideAutoCompletions()
{
completer()->popup()->hide();
}
// #include "data/query/QueryTree.h"
std::deque<SearchMatch> QtSmartSearchBox::getMatchesForInput(const std::string& text) const
{
// return SearchMatch::stringDequeToSearchMatchDeque(QueryTree::tokenizeQuery(text));
return std::deque<SearchMatch>(1, SearchMatch(text));
}
+16 -11
View File
@@ -3,23 +3,22 @@
#include <deque>
#include <memory>
#include <vector>
#include <QLineEdit>
#include <QPushButton>
#include "data/search/SearchMatch.h"
class QtQueryElement
class QtSearchElement
: public QPushButton
{
Q_OBJECT
signals:
void wasChecked(QtQueryElement*);
void wasChecked(QtSearchElement*);
public:
QtQueryElement(const QString& text, QWidget* parent);
QtSearchElement(const QString& text, QWidget* parent);
private slots:
void onChecked(bool);
@@ -39,7 +38,7 @@ public:
virtual ~QtSmartSearchBox();
void setAutocompletionList(const std::vector<SearchMatch>& autocompletionList);
void setMatches(const std::deque<SearchMatch>& matches);
void setMatches(const std::vector<SearchMatch>& matches);
void setFocus();
protected:
@@ -59,17 +58,19 @@ private slots:
void onAutocompletionHighlighted(const SearchMatch& match);
void onAutocompletionActivated(const SearchMatch& match);
void onElementSelected(QtQueryElement* element);
void onElementSelected(QtSearchElement* element);
private:
void moveCursor(int offset);
void moveCursorTo(int goal);
void matchToToken(const SearchMatch& match);
void searchMatchToToken(const SearchMatch& match);
void addMatch(const SearchMatch& match);
void addMatchAndUpdate(const SearchMatch& match);
void clearMatches();
void setEditText(const QString& text);
bool editTextToElement();
void editElement(QtQueryElement* element);
void editElement(QtSearchElement* element);
void updateElements();
void layoutElements();
@@ -87,11 +88,15 @@ private:
void requestAutoCompletions() const;
void hideAutoCompletions();
std::deque<SearchMatch> getMatchesForInput(const std::string& text) const;
bool m_allowMultipleElements;
bool m_allowTextChange;
QString m_oldText;
std::deque<SearchMatch> m_tokens;
std::vector<std::shared_ptr<QtQueryElement>> m_elements;
std::deque<SearchMatch> m_matches;
std::vector<std::shared_ptr<QtSearchElement>> m_elements;
size_t m_cursorIndex;
+3 -3
View File
@@ -34,7 +34,7 @@ void QtSearchView::refreshView()
m_refreshViewFunctor();
}
void QtSearchView::setMatches(const std::deque<SearchMatch>& matches)
void QtSearchView::setMatches(const std::vector<SearchMatch>& matches)
{
m_setMatchesFunctor(matches);
}
@@ -53,10 +53,10 @@ void QtSearchView::doRefreshView()
{
setStyleSheet();
m_widget->refreshStyle();
m_widget->setMatches(std::deque<SearchMatch>());
m_widget->setMatches(std::vector<SearchMatch>());
}
void QtSearchView::doSetMatches(const std::deque<SearchMatch>& matches)
void QtSearchView::doSetMatches(const std::vector<SearchMatch>& matches)
{
m_widget->setMatches(matches);
}
+3 -3
View File
@@ -19,20 +19,20 @@ public:
virtual void refreshView();
// SearchView implementation
virtual void setMatches(const std::deque<SearchMatch>& matches);
virtual void setMatches(const std::vector<SearchMatch>& matches);
virtual void setFocus();
virtual void setAutocompletionList(const std::vector<SearchMatch>& autocompletionList);
private:
void doRefreshView();
void doSetMatches(const std::deque<SearchMatch>& matches);
void doSetMatches(const std::vector<SearchMatch>& matches);
void doSetFocus();
void doSetAutocompletionList(const std::vector<SearchMatch>& autocompletionList);
void setStyleSheet();
QtThreadedFunctor<> m_refreshViewFunctor;
QtThreadedFunctor<const std::deque<SearchMatch>&> m_setMatchesFunctor;
QtThreadedFunctor<const std::vector<SearchMatch>&> m_setMatchesFunctor;
QtThreadedFunctor<> m_setFocusFunctor;
QtThreadedFunctor<const std::vector<SearchMatch>&> m_setAutocompletionListFunctor;
+1 -5
View File
@@ -115,11 +115,7 @@ void Application::handleMessage(MessageFinishedParsing* message)
if (!mainId)
{
std::vector<Id> ids = m_storageCache->getTokenIdsForQuery("'file'");
if (ids.size())
{
mainId = ids[0];
}
mainId = 1;
}
if (mainId)
-11
View File
@@ -159,17 +159,6 @@ add_files(
data/parser/ParseVariable.cpp
data/parser/ParseVariable.h
data/query/QueryCommand.cpp
data/query/QueryCommand.h
data/query/QueryNode.cpp
data/query/QueryNode.h
data/query/QueryOperator.cpp
data/query/QueryOperator.h
data/query/QueryToken.cpp
data/query/QueryToken.h
data/query/QueryTree.cpp
data/query/QueryTree.h
data/search/SearchIndex.cpp
data/search/SearchIndex.h
data/search/SearchNode.cpp
@@ -99,7 +99,7 @@ void FeatureController::handleMessage(MessageActivateTokenLocation* message)
void FeatureController::handleMessage(MessageSearch* message)
{
MessageActivateTokens m(m_storageAccess->getTokenIdsForQuery(message->getQuery()));
MessageActivateTokens m(m_storageAccess->getTokenIdsForMatches(message->getMatches()));
m.undoRedoType = message->undoRedoType;
m.dispatchImmediately();
}
@@ -19,7 +19,7 @@ void SearchController::handleMessage(MessageActivateEdge* message)
return;
}
getView()->setMatches(std::deque<SearchMatch>());
getView()->setMatches(std::vector<SearchMatch>());
}
void SearchController::handleMessage(MessageActivateFile* message)
@@ -28,9 +28,9 @@ void SearchController::handleMessage(MessageActivateFile* message)
match.fullName = message->filePath.fileName();
match.nodeType = Node::NODE_FILE;
match.tokenIds.insert(m_storageAccess->getTokenIdForFileNode(message->filePath));
match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN;
match.searchType = SearchMatch::SEARCH_TOKEN;
getView()->setMatches(std::deque<SearchMatch>(1, match));
getView()->setMatches(std::vector<SearchMatch>(1, match));
}
void SearchController::handleMessage(MessageActivateNode* message)
@@ -39,9 +39,9 @@ void SearchController::handleMessage(MessageActivateNode* message)
match.fullName = message->name;
match.nodeType = message->type;
match.tokenIds.insert(message->tokenId);
match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN;
match.searchType = SearchMatch::SEARCH_TOKEN;
getView()->setMatches(std::deque<SearchMatch>(1, match));
getView()->setMatches(std::vector<SearchMatch>(1, match));
}
void SearchController::handleMessage(MessageFind* message)
@@ -51,7 +51,7 @@ void SearchController::handleMessage(MessageFind* message)
void SearchController::handleMessage(MessageFinishedParsing* message)
{
getView()->setMatches(std::deque<SearchMatch>());
getView()->setMatches(std::vector<SearchMatch>());
}
void SearchController::handleMessage(MessageSearch* message)
@@ -135,7 +135,7 @@ void UndoRedoController::handleMessage(MessageRefresh* message)
void UndoRedoController::handleMessage(MessageSearch* message)
{
if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() &&
static_cast<MessageSearch*>(m_lastCommand.message.get())->getQuery() == message->getQuery())
static_cast<MessageSearch*>(m_lastCommand.message.get())->getMatchesAsString() == message->getMatchesAsString())
{
return;
}
+3 -2
View File
@@ -6,7 +6,8 @@
class SearchController;
class SearchView : public View
class SearchView
: public View
{
public:
SearchView(ViewLayout* viewLayout);
@@ -14,7 +15,7 @@ public:
virtual std::string getName() const;
virtual void setMatches(const std::deque<SearchMatch>& matches) = 0;
virtual void setMatches(const std::vector<SearchMatch>& matches) = 0;
virtual void setFocus() = 0;
virtual void setAutocompletionList(const std::vector<SearchMatch>& autocompletionList) = 0;
+18 -30
View File
@@ -17,7 +17,6 @@
#include "data/parser/ParseLocation.h"
#include "data/parser/ParseTypeUsage.h"
#include "data/parser/ParseVariable.h"
#include "data/query/QueryTree.h"
#include "data/type/DataType.h"
#include "settings/ApplicationSettings.h"
@@ -563,7 +562,7 @@ std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& qu
{
if (!match.tokenIds.size())
{
match.queryNodeType = QueryNode::QUERYNODETYPE_COMMAND;
match.searchType = SearchMatch::SEARCH_COMMAND;
continue;
}
@@ -577,7 +576,8 @@ std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& qu
{
match.typeName = Edge::getTypeString(Edge::intToType(m_sqliteStorage.getEdgeById(elementId).type));
}
match.queryNodeType = QueryNode::QUERYNODETYPE_TOKEN;
match.searchType = SearchMatch::SEARCH_TOKEN;
}
return matches;
@@ -676,38 +676,26 @@ Id Storage::getActiveNodeIdForLocationId(Id locationId) const
return activeElementId;
}
std::vector<Id> Storage::getTokenIdsForQuery(std::string query) const // TODO: refactor query stuff! (don't store info in string
std::vector<Id> Storage::getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const
{
std::set<Id> idSet;
for (const SearchMatch& match : matches)
{
std::vector<SearchMatch> ms = getAutocompletionMatches("", match.fullName);
for (size_t i = 0; i < ms.size(); i++)
{
utility::append(idSet, ms[i].tokenIds);
break;
}
}
std::vector<Id> ids;
std::deque<std::string> tokenizedQuery = QueryTree::tokenizeQuery(query);
if (tokenizedQuery.size() == 0)
for (std::set<Id>::const_iterator it = idSet.begin(); it != idSet.end(); it++)
{
return ids;
ids.push_back(*it);
}
std::string tokenName = tokenizedQuery[0];
tokenName.erase(std::remove(tokenName.begin(), tokenName.end(), '"'), tokenName.end());
const size_t delimiterPos = tokenName.rfind(',');
if (delimiterPos != tokenName.npos)
{
ids.push_back(std::stoi(tokenName.substr(delimiterPos + 1, tokenName.size() - (delimiterPos + 1))));
}
else
{
std::vector<SearchMatch> matches = getAutocompletionMatches("", tokenName);
std::set<Id> idSet;
for (size_t i = 0; i < matches.size(); i++)
{
utility::append(idSet, matches[i].tokenIds);
}
for (std::set<Id>::const_iterator it = idSet.begin(); it != idSet.end(); it++)
{
ids.push_back(*it);
}
}
return ids;
}
+1 -1
View File
@@ -121,7 +121,7 @@ public:
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
virtual Id getActiveNodeIdForLocationId(Id locationId) const;
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
virtual std::vector<Id> getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const;
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const;
+3 -2
View File
@@ -5,8 +5,9 @@ void StorageCache::clear()
m_queryToTokenIds.clear();
}
std::vector<Id> StorageCache::getTokenIdsForQuery(std::string query) const
std::vector<Id> StorageCache::getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const
{
std::string query = SearchMatch::searchMatchesToString(matches);
std::map<std::string, std::vector<Id>>::const_iterator it = m_queryToTokenIds.find(query);
if (it != m_queryToTokenIds.end())
@@ -14,7 +15,7 @@ std::vector<Id> StorageCache::getTokenIdsForQuery(std::string query) const
return it->second;
}
std::vector<Id> ids = StorageAccessProxy::getTokenIdsForQuery(query);
std::vector<Id> ids = StorageAccessProxy::getTokenIdsForMatches(matches);
m_queryToTokenIds.emplace(query, ids);
+1 -1
View File
@@ -11,7 +11,7 @@ class StorageCache
public:
void clear();
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
virtual std::vector<Id> getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const;
private:
mutable std::map<std::string, std::vector<Id>> m_queryToTokenIds;
+1 -1
View File
@@ -34,7 +34,7 @@ public:
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const = 0;
virtual Id getActiveNodeIdForLocationId(Id locationId) const = 0;
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const = 0;
virtual std::vector<Id> getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const = 0;
virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const = 0;
+2 -2
View File
@@ -112,11 +112,11 @@ Id StorageAccessProxy::getActiveNodeIdForLocationId(Id locationId) const
return 0;
}
std::vector<Id> StorageAccessProxy::getTokenIdsForQuery(std::string query) const
std::vector<Id> StorageAccessProxy::getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const
{
if (hasSubject())
{
return m_subject->getTokenIdsForQuery(query);
return m_subject->getTokenIdsForMatches(matches);
}
return std::vector<Id>();
+1 -1
View File
@@ -26,7 +26,7 @@ public:
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId, Id* declarationId) const;
virtual Id getActiveNodeIdForLocationId(Id locationId) const;
virtual std::vector<Id> getTokenIdsForQuery(std::string query) const;
virtual std::vector<Id> getTokenIdsForMatches(const std::vector<SearchMatch>& matches) const;
virtual Id getTokenIdForFileNode(const FilePath& filePath) const;
virtual std::vector<Id> getTokenIdsForAggregationEdge(Id sourceId, Id targetId) const;
-113
View File
@@ -1,113 +0,0 @@
#include "data/query/QueryCommand.h"
#include <algorithm>
std::map<std::string, QueryCommand::CommandType> QueryCommand::getCommandTypeMap()
{
static std::map<std::string, CommandType> commandMap;
if (commandMap.size())
{
return commandMap;
}
commandMap.emplace("undefined", COMMAND_UNDEFINED);
commandMap.emplace("member", COMMAND_MEMBER);
commandMap.emplace("child", COMMAND_MEMBER);
commandMap.emplace("parent", COMMAND_PARENT);
commandMap.emplace("function", COMMAND_FUNCTION);
commandMap.emplace("variable", COMMAND_GLOBAL_VARIABLE);
commandMap.emplace("global", COMMAND_GLOBAL_VARIABLE);
commandMap.emplace("class", COMMAND_CLASS);
commandMap.emplace("method", COMMAND_METHOD);
commandMap.emplace("field", COMMAND_FIELD);
commandMap.emplace("namespace", COMMAND_NAMESPACE);
commandMap.emplace("struct", COMMAND_STRUCT);
commandMap.emplace("enum", COMMAND_ENUM);
commandMap.emplace("enum-constant", COMMAND_ENUM_CONSTANT);
commandMap.emplace("typedef", COMMAND_TYPEDEF);
commandMap.emplace("const", COMMAND_CONST);
commandMap.emplace("static", COMMAND_STATIC);
commandMap.emplace("virtual", COMMAND_VIRTUAL);
commandMap.emplace("abstract", COMMAND_PURE_VIRTUAL);
commandMap.emplace("pure-virtual", COMMAND_PURE_VIRTUAL);
commandMap.emplace("public", COMMAND_PUBLIC);
commandMap.emplace("protected", COMMAND_PROTECTED);
commandMap.emplace("private", COMMAND_PRIVATE);
commandMap.emplace("caller", COMMAND_CALLER);
commandMap.emplace("callee", COMMAND_CALLEE);
commandMap.emplace("usage", COMMAND_USAGE);
commandMap.emplace("base", COMMAND_SUPER_CLASS);
commandMap.emplace("super", COMMAND_SUPER_CLASS);
commandMap.emplace("derived", COMMAND_SUB_CLASS);
commandMap.emplace("subclass", COMMAND_SUB_CLASS);
commandMap.emplace("file", COMMAND_FILE);
return commandMap;
}
QueryCommand::QueryCommand(std::string name)
: QueryNode(QueryNode::QUERYNODETYPE_COMMAND)
, m_type(COMMAND_INVALID)
{
name.erase(std::remove(name.begin(), name.end(), BOUNDARY), name.end());
m_name = name;
std::map<std::string, CommandType> commandMap = getCommandTypeMap();
std::map<std::string, CommandType>::iterator it = commandMap.find(name);
if (it != commandMap.end())
{
m_type = it->second;
}
}
QueryCommand::~QueryCommand()
{
}
bool QueryCommand::isCommand() const
{
return true;
}
bool QueryCommand::isOperator() const
{
return false;
}
bool QueryCommand::isToken() const
{
return false;
}
bool QueryCommand::derivedIsComplete() const
{
return m_type != COMMAND_INVALID;
}
std::string QueryCommand::getName() const
{
return m_name;
}
void QueryCommand::print(std::ostream& ostream) const
{
ostream << BOUNDARY << m_name << BOUNDARY;
}
QueryCommand::CommandType QueryCommand::getType() const
{
return m_type;
}
const char QueryCommand::BOUNDARY = '\'';
-75
View File
@@ -1,75 +0,0 @@
#ifndef QUERY_COMMAND_H
#define QUERY_COMMAND_H
#include <map>
#include "data/query/QueryNode.h"
class QueryCommand
: public QueryNode
{
public:
enum CommandType
{
COMMAND_INVALID,
COMMAND_UNDEFINED,
COMMAND_MEMBER,
COMMAND_PARENT,
COMMAND_FUNCTION,
COMMAND_GLOBAL_VARIABLE,
COMMAND_CLASS,
COMMAND_METHOD,
COMMAND_FIELD,
COMMAND_NAMESPACE,
COMMAND_STRUCT,
COMMAND_ENUM,
COMMAND_ENUM_CONSTANT,
COMMAND_TYPEDEF,
COMMAND_CONST,
COMMAND_STATIC,
COMMAND_VIRTUAL,
COMMAND_PURE_VIRTUAL,
COMMAND_PUBLIC,
COMMAND_PROTECTED,
COMMAND_PRIVATE,
COMMAND_CALLER,
COMMAND_CALLEE,
COMMAND_USAGE,
COMMAND_SUPER_CLASS,
COMMAND_SUB_CLASS,
COMMAND_FILE
};
static std::map<std::string, CommandType> getCommandTypeMap();
QueryCommand(std::string name);
~QueryCommand();
virtual bool isCommand() const;
virtual bool isOperator() const;
virtual bool isToken() const;
virtual bool derivedIsComplete() const;
virtual std::string getName() const;
virtual void print(std::ostream& ostream) const;
CommandType getType() const;
static const char BOUNDARY;
private:
CommandType m_type;
std::string m_name;
};
#endif // QUERY_COMMAND_H
-84
View File
@@ -1,84 +0,0 @@
#include "data/query/QueryNode.h"
QueryNode::QueryNode(QueryNodeType queryNodeType)
: m_nodeType(queryNodeType)
, m_isGroup(false)
, m_isComplete(true)
{
}
QueryNode::~QueryNode()
{
}
void QueryNode::print(std::ostream& ostream, int n) const
{
for (int i = 0; i < n; i++)
{
ostream << '\t';
}
if (isGroup())
{
ostream << '(';
}
print(ostream);
if (isGroup())
{
ostream << ')';
}
if (!isComplete())
{
ostream << " INVALID";
}
ostream << '\n';
}
bool QueryNode::isGroup() const
{
return m_isGroup;
}
void QueryNode::setIsGroup(bool isGroup)
{
m_isGroup = isGroup;
}
bool QueryNode::isComplete() const
{
return m_isComplete && derivedIsComplete();
}
void QueryNode::setIsComplete(bool isComplete)
{
m_isComplete = isComplete;
}
QueryNode::QueryNodeType QueryNode::getQueryNodeType() const
{
return m_nodeType;
}
std::string QueryNode::queryNodeTypeToString(const QueryNodeType& type)
{
switch(type)
{
case QUERYNODETYPE_NONE:
return "none";
case QUERYNODETYPE_COMMAND:
return "command";
case QUERYNODETYPE_TOKEN:
return "token";
case QUERYNODETYPE_OPERATOR:
return "operator";
}
}
std::string QueryNode::getQueryNodeTypeAsString() const
{
return queryNodeTypeToString(m_nodeType);
}
-50
View File
@@ -1,50 +0,0 @@
#ifndef QUERY_NODE_H
#define QUERY_NODE_H
#include <ostream>
#include <string>
class QueryNode
{
public:
enum QueryNodeType
{
QUERYNODETYPE_NONE,
QUERYNODETYPE_TOKEN,
QUERYNODETYPE_COMMAND,
QUERYNODETYPE_OPERATOR
};
static std::string queryNodeTypeToString(const QueryNodeType& type);
QueryNode(QueryNodeType queryNodeType = QUERYNODETYPE_NONE);
virtual ~QueryNode();
virtual bool isCommand() const = 0;
virtual bool isOperator() const = 0;
virtual bool isToken() const = 0;
virtual bool derivedIsComplete() const = 0;
virtual std::string getName() const = 0;
virtual void print(std::ostream& ostream) const = 0;
virtual void print(std::ostream& ostream, int n) const;
bool isGroup() const;
void setIsGroup(bool isGroup);
bool isComplete() const;
void setIsComplete(bool isComplete);
QueryNodeType getQueryNodeType() const;
std::string getQueryNodeTypeAsString() const;
private:
QueryNodeType m_nodeType;
bool m_isGroup;
bool m_isComplete;
};
#endif // QUERY_NODE_H
-157
View File
@@ -1,157 +0,0 @@
#include "data/query/QueryOperator.h"
#include "data/query/QueryCommand.h"
#include "data/query/QueryToken.h"
const std::map<char, QueryOperator::OperatorType>& QueryOperator::getOperatorTypeMap()
{
static std::map<char, OperatorType> operatorMap;
if (operatorMap.size())
{
return operatorMap;
}
operatorMap.emplace(' ', OPERATOR_NONE);
operatorMap.emplace('!', OPERATOR_NOT);
operatorMap.emplace('.', OPERATOR_HAS);
operatorMap.emplace('+', OPERATOR_SUB);
operatorMap.emplace('&', OPERATOR_AND);
operatorMap.emplace('|', OPERATOR_OR);
operatorMap.emplace(QueryToken::BOUNDARY, OPERATOR_TOKEN);
operatorMap.emplace(QueryCommand::BOUNDARY, OPERATOR_COMMAND);
operatorMap.emplace('(', OPERATOR_GROUP_OPEN);
operatorMap.emplace(')', OPERATOR_GROUP_CLOSE);
return operatorMap;
}
QueryOperator::OperatorType QueryOperator::getOperatorType(char c)
{
const std::map<char, OperatorType>& operatorMap = getOperatorTypeMap();
std::map<char, OperatorType>::const_iterator it = operatorMap.find(c);
if (it != operatorMap.end())
{
return it->second;
}
return OPERATOR_NONE;
}
char QueryOperator::getOperator(OperatorType t)
{
for (const std::pair<char, OperatorType>& p : getOperatorTypeMap())
{
if (p.second == t)
{
return p.first;
}
}
return '\0';
}
QueryOperator::QueryOperator(OperatorType type, bool isImplicit)
: QueryNode(QueryNode::QUERYNODETYPE_OPERATOR)
, m_type(type)
, m_isImplicit(isImplicit)
{
}
QueryOperator::~QueryOperator()
{
}
bool QueryOperator::isCommand() const
{
return false;
}
bool QueryOperator::isOperator() const
{
return true;
}
bool QueryOperator::isToken() const
{
return false;
}
bool QueryOperator::derivedIsComplete() const
{
if (m_type == OPERATOR_NOT)
{
return bool(getRight());
}
return getLeft() && getRight();
}
std::string QueryOperator::getName() const
{
return std::string(1, getOperator(m_type));
}
void QueryOperator::print(std::ostream& ostream) const
{
ostream << getOperator(m_type);
if (isImplicit())
{
ostream << " IMPLICIT";
}
}
void QueryOperator::print(std::ostream& ostream, int n) const
{
if (m_left)
{
m_left->print(ostream, n + 1);
}
QueryNode::print(ostream, n);
if (m_right)
{
m_right->print(ostream, n + 1);
}
}
std::shared_ptr<QueryNode> QueryOperator::getLeft() const
{
return m_left;
}
void QueryOperator::setLeft(std::shared_ptr<QueryNode> node)
{
m_left = node;
}
std::shared_ptr<QueryNode> QueryOperator::getRight() const
{
return m_right;
}
void QueryOperator::setRight(std::shared_ptr<QueryNode> node)
{
m_right = node;
}
QueryOperator::OperatorType QueryOperator::getType() const
{
return m_type;
}
bool QueryOperator::lowerPrecedence(const QueryOperator& other)
{
return m_type < other.m_type;
}
bool QueryOperator::isImplicit() const
{
return m_isImplicit;
}
-68
View File
@@ -1,68 +0,0 @@
#ifndef QUERY_OPERATOR_H
#define QUERY_OPERATOR_H
#include <map>
#include <memory>
#include "data/query/QueryNode.h"
class QueryOperator
: public QueryNode
{
public:
enum OperatorType
{
OPERATOR_NONE,
OPERATOR_NOT,
OPERATOR_HAS,
OPERATOR_SUB,
OPERATOR_AND,
OPERATOR_OR,
OPERATOR_TOKEN,
OPERATOR_COMMAND,
OPERATOR_GROUP_OPEN,
OPERATOR_GROUP_CLOSE
};
static const std::map<char, OperatorType>& getOperatorTypeMap();
static OperatorType getOperatorType(char c);
static char getOperator(OperatorType t);
QueryOperator(OperatorType type, bool isImplicit);
~QueryOperator();
virtual bool isCommand() const;
virtual bool isOperator() const;
virtual bool isToken() const;
virtual bool derivedIsComplete() const;
virtual std::string getName() const;
virtual void print(std::ostream& ostream) const;
virtual void print(std::ostream& ostream, int n) const;
std::shared_ptr<QueryNode> getLeft() const;
void setLeft(std::shared_ptr<QueryNode> node);
std::shared_ptr<QueryNode> getRight() const;
void setRight(std::shared_ptr<QueryNode> node);
OperatorType getType() const;
bool lowerPrecedence(const QueryOperator& other);
bool isImplicit() const;
private:
std::shared_ptr<QueryNode> m_left;
std::shared_ptr<QueryNode> m_right;
const OperatorType m_type;
bool m_isImplicit;
};
#endif // QUERY_OPERATOR_H
-82
View File
@@ -1,82 +0,0 @@
#include "data/query/QueryToken.h"
#include <algorithm>
#include <deque>
#include "utility/utilityString.h"
QueryToken::QueryToken(std::string name)
: QueryNode(QueryNode::QUERYNODETYPE_TOKEN)
{
name.erase(std::remove(name.begin(), name.end(), BOUNDARY), name.end());
std::deque<std::string> names = utility::split(name, DELIMITER);
m_tokenName = names.front();
names.pop_front();
while (names.size())
{
std::stringstream ss;
ss << names.front();
names.pop_front();
Id tokenId = 0;
ss >> tokenId;
if (tokenId)
{
m_tokenIds.insert(tokenId);
}
}
}
QueryToken::~QueryToken()
{
}
bool QueryToken::isCommand() const
{
return false;
}
bool QueryToken::isOperator() const
{
return false;
}
bool QueryToken::isToken() const
{
return true;
}
bool QueryToken::derivedIsComplete() const
{
return true;
}
std::string QueryToken::getName() const
{
return m_tokenName;
}
void QueryToken::print(std::ostream& ostream) const
{
ostream << BOUNDARY << m_tokenName;
for (Id tokenId : m_tokenIds)
{
ostream << DELIMITER << tokenId;
}
ostream << BOUNDARY;
}
const std::string& QueryToken::getTokenName() const
{
return m_tokenName;
}
const std::set<Id>& QueryToken::getTokenIds() const
{
return m_tokenIds;
}
const char QueryToken::DELIMITER = ',';
const char QueryToken::BOUNDARY = '"';
-37
View File
@@ -1,37 +0,0 @@
#ifndef QUERY_TOKEN_H
#define QUERY_TOKEN_H
#include <set>
#include "data/query/QueryNode.h"
#include "utility/types.h"
class QueryToken
: public QueryNode
{
public:
QueryToken(std::string name);
~QueryToken();
virtual bool isCommand() const;
virtual bool isOperator() const;
virtual bool isToken() const;
virtual bool derivedIsComplete() const;
virtual std::string getName() const;
virtual void print(std::ostream& ostream) const;
const std::string& getTokenName() const;
const std::set<Id>& getTokenIds() const;
static const char DELIMITER;
static const char BOUNDARY;
private:
std::string m_tokenName;
std::set<Id> m_tokenIds;
};
#endif // QUERY_TOKEN_H
-321
View File
@@ -1,321 +0,0 @@
#include "data/query/QueryTree.h"
#include "data/query/QueryCommand.h"
#include "data/query/QueryNode.h"
#include "data/query/QueryOperator.h"
#include "data/query/QueryToken.h"
#include "utility/utilityString.h"
std::deque<std::string> QueryTree::tokenizeQuery(const std::string& query)
{
std::deque<std::string> tokensTmp = utility::split(query, QueryOperator::getOperator(QueryOperator::OPERATOR_NONE));
for (const std::pair<char, QueryOperator::OperatorType>& p : QueryOperator::getOperatorTypeMap())
{
tokensTmp = utility::tokenize(tokensTmp, p.first);
}
char operatorToken = QueryOperator::getOperator(QueryOperator::OPERATOR_TOKEN);
char operatorCommand = QueryOperator::getOperator(QueryOperator::OPERATOR_COMMAND);
bool isToken = false;
bool isCommand = false;
std::string token;
std::deque<std::string> tokens;
while (tokensTmp.size())
{
std::string tokenTmp = tokensTmp.front();
tokensTmp.pop_front();
token += tokenTmp;
if (tokenTmp.size() == 1)
{
if (tokenTmp[0] == operatorToken && !isCommand)
{
isToken = !isToken;
}
else if (tokenTmp[0] == operatorCommand && !isToken)
{
isCommand = !isCommand;
}
}
if ((!isToken && !isCommand) || (!tokensTmp.size() && token.size()))
{
tokens.push_back(token);
token.clear();
}
}
return tokens;
}
std::string QueryTree::getTokenName(const std::string& token)
{
if (token.size() > 2 && token.front() == QueryToken::BOUNDARY && token.back() == QueryToken::BOUNDARY)
{
return QueryToken(token).getName();
}
else if (token.size() > 2 && token.front() == QueryCommand::BOUNDARY && token.back() == QueryCommand::BOUNDARY)
{
return QueryCommand(token).getName();
}
return token;
}
std::string QueryTree::getTokenTypeName(const QueryNode::QueryNodeType& type)
{
return QueryNode::queryNodeTypeToString(type);
}
QueryNode::QueryNodeType QueryTree::getTokenType(const std::string& token)
{
if (token.size() > 2 && token.front() == QueryToken::BOUNDARY && token.back() == QueryToken::BOUNDARY)
{
return QueryNode::QUERYNODETYPE_TOKEN;
}
else if (token.size() > 2 && token.front() == QueryCommand::BOUNDARY && token.back() == QueryCommand::BOUNDARY)
{
return QueryNode::QUERYNODETYPE_COMMAND;
}
else if (token.size() == 1 && QueryOperator::getOperatorType(token.front()) != QueryOperator::OPERATOR_NONE)
{
return QueryNode::QUERYNODETYPE_OPERATOR;
}
return QueryNode::QUERYNODETYPE_NONE;
}
QueryTree::QueryTree()
: m_valid(true)
{
}
QueryTree::QueryTree(const std::string& query)
: m_valid(true)
{
build(query);
}
QueryTree::~QueryTree()
{
}
std::shared_ptr<QueryNode> QueryTree::getRoot() const
{
return m_root;
}
bool QueryTree::isValid() const
{
return m_valid;
}
void QueryTree::build(const std::string& query)
{
std::deque<std::string> tokens = tokenizeQuery(query);
m_query = utility::join(tokens, ' ');
m_valid = true;
m_root = buildTree(tokens, nullptr);
}
void QueryTree::print(std::ostream& ostream) const
{
ostream << m_query;
if (!m_valid)
{
ostream << " INVALID";
}
ostream << '\n';
if (m_root)
{
m_root->print(ostream, 0);
}
}
std::shared_ptr<QueryNode> QueryTree::buildTree(std::deque<std::string>& tokens, std::shared_ptr<QueryNode> frontNode)
{
std::shared_ptr<QueryNode> node = getNextNode(tokens);
std::shared_ptr<QueryOperator> operatorNode = std::dynamic_pointer_cast<QueryOperator>(node);
if (!node)
{
m_valid = false;
return nullptr;
}
if (frontNode)
{
if (node->isComplete())
{
std::shared_ptr<QueryOperator> subNode = std::make_shared<QueryOperator>(QueryOperator::OPERATOR_SUB, true);
subNode->setLeft(frontNode);
subNode->setRight(node);
node = subNode;
}
else if (node->isOperator() && operatorNode)
{
operatorNode->setLeft(frontNode);
}
else
{
m_valid = false;
}
}
if (tokens.size())
{
if (node->isComplete())
{
node = buildTree(tokens, node);
}
else if (node->isOperator() && operatorNode)
{
std::shared_ptr<QueryNode> rightNode = buildTree(tokens, nullptr);
std::shared_ptr<QueryOperator> rightOperatorNode = std::dynamic_pointer_cast<QueryOperator>(rightNode);
if (!rightNode)
{
m_valid = false;
}
else if (rightNode->isOperator() && !rightNode->isGroup() &&
operatorNode->lowerPrecedence(*rightOperatorNode.get()))
{
operatorNode->setRight(rightOperatorNode->getLeft());
rightOperatorNode->setLeft(operatorNode);
node = rightNode;
}
else
{
operatorNode->setRight(rightNode);
}
}
else
{
m_valid = false;
}
}
if (!node || !node->isComplete())
{
m_valid = false;
}
return node;
}
std::shared_ptr<QueryNode> QueryTree::buildGroup(std::deque<std::string>& tokens, QueryOperator::OperatorType closeType)
{
std::deque<std::string> group;
std::string name;
char delimiter = QueryOperator::getOperator(closeType);
bool valid = true;
while (tokens.size() > 0 && tokens.front() != std::string(1, delimiter))
{
group.push_back(tokens.front());
name += tokens.front();
tokens.pop_front();
}
if (tokens.size())
{
tokens.pop_front();
}
else
{
valid = false;
m_valid = false;
}
if (!group.size())
{
return nullptr;
}
std::shared_ptr<QueryNode> groupNode = buildTree(group, nullptr);
groupNode->setIsGroup(true);
groupNode->setIsComplete(valid);
return groupNode;
}
std::shared_ptr<QueryNode> QueryTree::getNextNode(std::deque<std::string>& tokens)
{
while (tokens.size())
{
std::string token = tokens.front();
tokens.pop_front();
QueryOperator::OperatorType type = QueryOperator::getOperatorType(token[0]);
switch (type)
{
case QueryOperator::OPERATOR_NOT:
case QueryOperator::OPERATOR_SUB:
case QueryOperator::OPERATOR_HAS:
case QueryOperator::OPERATOR_AND:
case QueryOperator::OPERATOR_OR:
return std::make_shared<QueryOperator>(type, false);
case QueryOperator::OPERATOR_TOKEN:
return createToken(token);
case QueryOperator::OPERATOR_COMMAND:
return createCommand(token);
case QueryOperator::OPERATOR_GROUP_OPEN:
return buildGroup(tokens, QueryOperator::OPERATOR_GROUP_CLOSE);
case QueryOperator::OPERATOR_GROUP_CLOSE:
m_valid = false;
break;
case QueryOperator::OPERATOR_NONE:
return createToken(token);
}
}
return nullptr;
}
std::shared_ptr<QueryNode> QueryTree::createCommand(const std::string& name)
{
if (name.size() < 3 || name.front() != QueryCommand::BOUNDARY || name.back() != QueryCommand::BOUNDARY)
{
m_valid = false;
}
std::shared_ptr<QueryCommand> node = std::make_shared<QueryCommand>(name);
if (node->getType() == QueryCommand::COMMAND_INVALID)
{
m_valid = false;
}
return node;
}
std::shared_ptr<QueryNode> QueryTree::createToken(const std::string& name)
{
if (name.size() < 3 || name.front() != QueryToken::BOUNDARY || name.back() != QueryToken::BOUNDARY)
{
m_valid = false;
}
return std::make_shared<QueryToken>(name);
}
std::ostream& operator<<(std::ostream& ostream, const QueryTree& tree)
{
tree.print(ostream);
return ostream;
}
-46
View File
@@ -1,46 +0,0 @@
#ifndef QUERY_TREE_H
#define QUERY_TREE_H
#include <deque>
#include <memory>
#include <ostream>
#include <string>
#include "data/query/QueryNode.h"
#include "data/query/QueryOperator.h"
class QueryTree
{
public:
static std::deque<std::string> tokenizeQuery(const std::string& query);
static std::string getTokenName(const std::string& token);
static QueryNode::QueryNodeType getTokenType(const std::string& token);
static std::string getTokenTypeName(const QueryNode::QueryNodeType& token);
QueryTree();
QueryTree(const std::string& query);
~QueryTree();
std::shared_ptr<QueryNode> getRoot() const;
bool isValid() const;
void build(const std::string& query);
void print(std::ostream& ostream) const;
private:
std::shared_ptr<QueryNode> buildTree(std::deque<std::string>& tokens, std::shared_ptr<QueryNode> frontNode);
std::shared_ptr<QueryNode> buildGroup(std::deque<std::string>& tokens, QueryOperator::OperatorType closeType);
std::shared_ptr<QueryNode> getNextNode(std::deque<std::string>& tokens);
std::shared_ptr<QueryNode> createCommand(const std::string& name);
std::shared_ptr<QueryNode> createToken(const std::string& name);
std::shared_ptr<QueryNode> m_root;
std::string m_query;
bool m_valid;
};
std::ostream& operator<<(std::ostream& ostream, const QueryTree& tree);
#endif // QUERY_TREE_H
+51 -102
View File
@@ -1,25 +1,8 @@
#include "data/search/SearchMatch.h"
#include <sstream>
#include <cstdlib>
#include "data/query/QueryCommand.h"
#include "data/query/QueryOperator.h"
#include "data/query/QueryToken.h"
#include "utility/logging/logging.h"
#include "utility/utilityString.h"
SearchMatch::SearchMatch()
: fullName("")
, typeName("")
, queryNodeType(QueryNode::QUERYNODETYPE_NONE)
{
}
SearchMatch::SearchMatch(const std::string& query)
{
decodeFromQuery(query);
}
void SearchMatch::log(const std::vector<SearchMatch>& matches, const std::string& query)
{
@@ -34,6 +17,52 @@ void SearchMatch::log(const std::vector<SearchMatch>& matches, const std::string
LOG_INFO(ss.str());
}
std::string SearchMatch::getSearchTypeName(SearchType type)
{
switch (type)
{
case SEARCH_NONE:
return "none";
case SEARCH_TOKEN:
return "token";
case SEARCH_COMMAND:
return "command";
case SEARCH_OPERATOR:
return "operator";
}
}
std::string SearchMatch::searchMatchesToString(const std::vector<SearchMatch>& matches)
{
std::stringstream ss;
for (size_t i = 0; i < matches.size(); i++)
{
ss << '@' << matches[i].fullName;
}
return ss.str();
}
SearchMatch::SearchMatch()
: fullName("")
, typeName("")
, searchType(SEARCH_NONE)
{
}
SearchMatch::SearchMatch(const std::string& query)
: fullName(query)
, typeName("")
, searchType(SEARCH_NONE)
{
}
bool SearchMatch::isValid() const
{
return searchType != SEARCH_NONE;
}
void SearchMatch::print(std::ostream& ostream) const
{
ostream << weight << '\t' << fullName << std::endl << '\t';
@@ -51,92 +80,12 @@ void SearchMatch::print(std::ostream& ostream) const
ostream << std::endl;
}
std::string SearchMatch::encodeForQuery() const
{
switch(queryNodeType)
{
case QueryNode::QUERYNODETYPE_COMMAND:
return QueryCommand::BOUNDARY + fullName + QueryCommand::BOUNDARY;
case QueryNode::QUERYNODETYPE_TOKEN:
{
std::stringstream ss;
ss << QueryToken::BOUNDARY << fullName;
for (Id tokenId : tokenIds)
{
ss << QueryToken::DELIMITER << tokenId;
}
ss << QueryToken::BOUNDARY;
return ss.str();
}
case QueryNode::QUERYNODETYPE_OPERATOR:
case QueryNode::QUERYNODETYPE_NONE:
return fullName;
}
}
void SearchMatch::decodeFromQuery(std::string query)
{
if (query.size() > 2 && query.front() == QueryToken::BOUNDARY && query.back() == QueryToken::BOUNDARY)
{
queryNodeType = QueryNode::QUERYNODETYPE_TOKEN;
query.erase(query.begin());
query.pop_back();
}
else if (query.size() > 2 && query.front() == QueryCommand::BOUNDARY && query.back() == QueryCommand::BOUNDARY)
{
queryNodeType = QueryNode::QUERYNODETYPE_COMMAND;
query.erase(query.begin());
query.pop_back();
}
else if (query.size() == 1 && QueryOperator::getOperatorType(query.front()) != QueryOperator::OPERATOR_NONE)
{
queryNodeType = QueryNode::QUERYNODETYPE_OPERATOR;
}
else
{
queryNodeType = QueryNode::QUERYNODETYPE_NONE;
}
std::vector<std::string> queryParts = utility::splitToVector(query, QueryToken::DELIMITER);
fullName = queryParts[0];
if (queryParts.size() > 1)
{
for (size_t i = 2; i < queryParts.size(); ++i)
{
tokenIds.insert(std::strtoul(queryParts[i].c_str(),nullptr,0));
}
}
}
std::deque<SearchMatch> SearchMatch::stringDequeToSearchMatchDeque(const std::deque<std::string>& stringDeque)
{
std::deque<SearchMatch> matchDeque;
for(std::string str : stringDeque)
{
matchDeque.push_back(SearchMatch(str));
}
return matchDeque;
}
std::deque<std::string> SearchMatch::searchMatchDequeToStringDeque(const std::deque<SearchMatch>& searchMatchDeque)
{
std::deque<std::string> stringDeque;
for(SearchMatch match : searchMatchDeque)
{
stringDeque.push_back(match.encodeForQuery());
}
return stringDeque;
}
std::string SearchMatch::searchMatchDequeToString(const std::deque<SearchMatch>& searchMatchDeque)
{
return utility::join(searchMatchDequeToStringDeque(searchMatchDeque), "");
}
std::string SearchMatch::getNodeTypeAsString() const
{
return Node::getTypeString(nodeType);
}
std::string SearchMatch::getSearchTypeName() const
{
return getSearchTypeName(searchType);
}
+17 -9
View File
@@ -1,39 +1,47 @@
#ifndef SEARCH_MATCH_H
#define SEARCH_MATCH_H
#include <deque>
#include <ostream>
#include <set>
#include <string>
#include <vector>
#include "data/graph/Node.h"
#include "data/query/QueryNode.h"
#include "utility/types.h"
struct SearchMatch
{
enum SearchType
{
SEARCH_NONE,
SEARCH_TOKEN,
SEARCH_COMMAND,
SEARCH_OPERATOR
};
static void log(const std::vector<SearchMatch>& matches, const std::string& query);
static std::deque<SearchMatch> stringDequeToSearchMatchDeque(const std::deque<std::string>& deque);
static std::deque<std::string> searchMatchDequeToStringDeque(const std::deque<SearchMatch>& deque);
static std::string searchMatchDequeToString(const std::deque<SearchMatch>& deque);
static std::string getSearchTypeName(SearchType type);
static std::string searchMatchesToString(const std::vector<SearchMatch>& matches);
SearchMatch();
SearchMatch(const std::string& query);
bool isValid() const;
void print(std::ostream& ostream) const;
std::string encodeForQuery() const;
void decodeFromQuery(std::string query);
std::string getNodeTypeAsString() const;
std::string getSearchTypeName() const;
std::string fullName;
std::string typeName;
Node::NodeType nodeType;
QueryNode::QueryNodeType queryNodeType;
SearchType searchType;
std::set<Id> tokenIds;
std::vector<size_t> indices;
size_t weight;
};
+2 -2
View File
@@ -33,9 +33,9 @@ std::string ColorScheme::getEdgeTypeColor(Edge::EdgeType type, const std::string
return getValue<std::string>(path, "#FFFFFF");
}
std::string ColorScheme::getQueryNodeTypeColor(QueryNode::QueryNodeType type, const std::string& state) const
std::string ColorScheme::getSearchTypeColor(const std::string& searchTypeName, const std::string& state) const
{
std::string path = "search/query/" + QueryNode::queryNodeTypeToString(type) + "/" + state;
std::string path = "search/query/" + searchTypeName + "/" + state;
return getValue<std::string>(path, "#FFFFFF");
}
+1 -2
View File
@@ -3,7 +3,6 @@
#include "data/graph/Node.h"
#include "data/graph/Edge.h"
#include "data/query/QueryNode.h"
#include "settings/Settings.h"
class ColorScheme
@@ -17,7 +16,7 @@ public:
std::string getNodeTypeColor(Node::NodeType type, const std::string& state = "normal") const;
std::string getEdgeTypeColor(Edge::EdgeType type, const std::string& state = "normal") const;
std::string getQueryNodeTypeColor(QueryNode::QueryNodeType type, const std::string& state = "normal") const;
std::string getSearchTypeColor(const std::string& searchTypeName, const std::string& state = "normal") const;
std::string getSyntaxColor(const std::string& key) const;
protected:
+5 -18
View File
@@ -1,8 +1,6 @@
#ifndef MESSAGE_SEARCH_H
#define MESSAGE_SEARCH_H
#include <deque>
#include "utility/messaging/Message.h"
#include "utility/utilityString.h"
@@ -12,12 +10,7 @@ class MessageSearch
: public Message<MessageSearch>
{
public:
MessageSearch(const std::string& query)
: m_query(query)
{
}
MessageSearch(const std::deque<SearchMatch>& matches)
MessageSearch(const std::vector<SearchMatch>& matches)
: m_matches(matches)
{
}
@@ -27,24 +20,18 @@ public:
return "MessageSearch";
}
std::string getQuery() const
std::string getMatchesAsString() const
{
if (m_query.size())
{
return m_query;
}
return utility::join(SearchMatch::searchMatchDequeToStringDeque(m_matches), "");
return SearchMatch::searchMatchesToString(m_matches);
}
const std::deque<SearchMatch>& getMatches() const
const std::vector<SearchMatch>& getMatches() const
{
return m_matches;
}
private:
const std::string m_query;
const std::deque<SearchMatch> m_matches;
const std::vector<SearchMatch> m_matches;
};
#endif // MESSAGE_SEARCH_H
+12
View File
@@ -1,6 +1,7 @@
#ifndef UTILITY_H
#define UTILITY_H
#include <deque>
#include <chrono>
#include <set>
@@ -23,6 +24,9 @@ namespace utility
template<typename T>
void append(std::set<T>& a, const std::set<T>& b);
template<typename T>
std::vector<T> toVector(const std::deque<T>& d);
bool intersectionPoint(Vec2f a1, Vec2f b1, Vec2f a2, Vec2f b2, Vec2f* i);
size_t digits(size_t n);
@@ -49,4 +53,12 @@ void utility::append(std::set<T>& a, const std::set<T>& b)
a.insert(b.begin(), b.end());
}
template<typename T>
std::vector<T> utility::toVector(const std::deque<T>& d)
{
std::vector<T> v;
v.insert(v.begin(), d.begin(), d.end());
return v;
}
#endif // UTILITY_H
-1
View File
@@ -20,7 +20,6 @@ add_files(
LogManagerTestSuite.h
MatrixBaseTestSuite.h
MessageQueueTestSuite.h
QueryTreeTestSuite.h
SettingsTestSuite.h
SearchIndexTestSuite.h
SqliteStorageTestSuite.h
-377
View File
@@ -1,377 +0,0 @@
#include "cxxtest/TestSuite.h"
#include "data/query/QueryTree.h"
class QueryTreeTestSuite : public CxxTest::TestSuite
{
public:
void test_empty_query()
{
TS_ASSERT_EQUALS(
printedQueryTree(""),
" INVALID\n"
);
}
void test_invalid_query()
{
TS_ASSERT_EQUALS(
printedQueryTree(" -"),
"- INVALID\n"
"\"-\"\n"
);
}
void test_command_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("'class'"),
"'class'\n"
"'class'\n"
);
}
void test_invalid_command_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("banana"),
"banana INVALID\n"
"\"banana\"\n"
);
}
void test_token_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A\""),
"\"A\"\n"
"\"A\"\n"
);
}
void test_invalid_token_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A"),
"\"A INVALID\n"
"\"A\"\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("\"\""),
"\"\" INVALID\n"
"\"\"\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("A\""),
"A \" INVALID\n"
" \"A\"\n"
"+ IMPLICIT\n"
" \"\"\n"
);
}
void test_token_query_with_id()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A,1\""),
"\"A,1\"\n"
"\"A,1\"\n"
);
}
void test_token_query_with_ids()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A,1,2\""),
"\"A,1,2\"\n"
"\"A,1,2\"\n"
);
}
void test_operator_not_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("!'field'"),
"! 'field'\n"
"!\n"
" 'field'\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("!!'field'"),
"! ! 'field'\n"
"!\n"
" !\n"
" 'field'\n"
);
}
void test_invalid_operator_not_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("!"),
"! INVALID\n"
"! INVALID\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("'field'!"),
"'field' ! INVALID\n"
" 'field'\n"
"! INVALID\n"
);
}
void test_operator_sub_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A\".\"B\""),
"\"A\" . \"B\"\n"
" \"A\"\n"
".\n"
" \"B\"\n"
);
}
void test_invalid_operator_sub_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A\"."),
"\"A\" . INVALID\n"
" \"A\"\n"
". INVALID\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("."),
". INVALID\n"
". INVALID\n"
);
TS_ASSERT_EQUALS(
printedQueryTree(".\"A\""),
". \"A\" INVALID\n"
". INVALID\n"
" \"A\"\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("\"A\"..\"B\""),
"\"A\" . . \"B\" INVALID\n"
" \"A\"\n"
".\n"
" . INVALID\n"
" \"B\"\n"
);
}
void test_operator_has_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A\".\"B\""),
"\"A\" . \"B\"\n"
" \"A\"\n"
".\n"
" \"B\"\n"
);
}
void test_operator_and_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A\"&\"B\""),
"\"A\" & \"B\"\n"
" \"A\"\n"
"&\n"
" \"B\"\n"
);
}
void test_operator_or_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A\"|\"B\""),
"\"A\" | \"B\"\n"
" \"A\"\n"
"|\n"
" \"B\"\n"
);
}
void test_operator_group_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("(\"A\")"),
"( \"A\" )\n"
"(\"A\")\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("(\"A\"|\"B\")"),
"( \"A\" | \"B\" )\n"
" \"A\"\n"
"(|)\n"
" \"B\"\n"
);
}
void test_invalid_operator_group_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("()"),
"( ) INVALID\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("(\"A\""),
"( \"A\" INVALID\n"
"(\"A\") INVALID\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("\"A\")"),
"\"A\" ) INVALID\n"
);
TS_ASSERT_EQUALS(
printedQueryTree(")("),
") ( INVALID\n"
);
}
void test_implicit_operator_sub_query()
{
TS_ASSERT_EQUALS(
printedQueryTree("\"A\"(\"B\")"),
"\"A\" ( \"B\" )\n"
" \"A\"\n"
"+ IMPLICIT\n"
" (\"B\")\n"
);
}
void test_operator_precedence_not_before_has()
{
TS_ASSERT_EQUALS(
printedQueryTree("!'struct'+!'const'"),
"! 'struct' + ! 'const'\n"
" !\n"
" 'struct'\n"
"+\n"
" !\n"
" 'const'\n"
);
}
void test_operator_precedence_has_before_sub()
{
TS_ASSERT_EQUALS(
printedQueryTree("'namespace'.'class'+'base'"),
"'namespace' . 'class' + 'base'\n"
" 'namespace'\n"
" .\n"
" 'class'\n"
"+\n"
" 'base'\n"
);
}
void test_operator_precedence_has_before_or()
{
TS_ASSERT_EQUALS(
printedQueryTree("'class'.'method'|'field'"),
"'class' . 'method' | 'field'\n"
" 'class'\n"
" .\n"
" 'method'\n"
"|\n"
" 'field'\n"
);
}
void test_operator_precedence_respects_groups()
{
TS_ASSERT_EQUALS(
printedQueryTree("'namespace'+('class'.'method')"),
"'namespace' + ( 'class' . 'method' )\n"
" 'namespace'\n"
"+\n"
" 'class'\n"
" (.)\n"
" 'method'\n"
);
TS_ASSERT_EQUALS(
printedQueryTree("'class'.('method'|'field')"),
"'class' . ( 'method' | 'field' )\n"
" 'class'\n"
".\n"
" 'method'\n"
" (|)\n"
" 'field'\n"
);
}
void test_spaces_get_stripped_out_of_query()
{
TS_ASSERT_EQUALS(
printedQueryTree(" \"Field \".('method' | 'field') +'const' | 'public' "),
"\"Field\" . ( 'method' | 'field' ) + 'const' | 'public'\n"
" \"Field\"\n"
" .\n"
" 'method'\n"
" (|)\n"
" 'field'\n"
" +\n"
" 'const'\n"
"|\n"
" 'public'\n"
);
}
private:
std::string printedQueryTree(std::string query) const
{
QueryTree tree(query);
std::stringstream ss;
tree.print(ss);
return ss.str();
}
};