From 023c6288d604d393e5a93cb4980c97b463dcf198 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Mon, 20 Aug 2018 23:22:50 +0200 Subject: [PATCH] logic: Fixed issues releated to real signatures in tooltips (issue #604) * Fixed crash when signature was wrongly recorded * Fixed line break at wrong position for template functions/methods * Fixed already qualified name replace with qualified name, repeating qualifiers --- src/lib/data/storage/PersistentStorage.cpp | 23 ++++++++++++++++++---- src/lib_utility/utility/utilityString.cpp | 21 +++++++++++++++++++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index e5514ae0..7009b932 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -1928,7 +1928,8 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no ); // if node has a signature location use that one - if (sigLoc) + // use while for breaking out + while (sigLoc) { struct Annotation { @@ -1941,6 +1942,16 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no std::vector lines = getFileContent(sigLoc->getFilePath())->getLines( sigLoc->getLineNumber(), sigLoc->getEndLocation()->getLineNumber()); + // check if signature location refers to correct locations in the code + // wrongly recorded signature locations of implicit template methods in C++ caused crashes + if (lines.empty() || + lines.size() != sigLoc->getOtherLocation()->getLineNumber() - sigLoc->getLineNumber() + 1 || + sigLoc->getColumnNumber() > lines[0].size() || + sigLoc->getOtherLocation()->getColumnNumber() > lines[lines.size() - 1].size()) + { + break; + } + std::shared_ptr file = getSourceLocationsForLinesInFile( sigLoc->getFilePath(), sigLoc->getStartLocation()->getLineNumber(), @@ -1956,13 +1967,13 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no Annotation annotation; annotation.locationId = loc->getLocationId(); - for (size_t i = 0; i < loc->getLineNumber() - sigLoc->getLineNumber(); i++) + for (size_t i = 0; i < loc->getLineNumber() - sigLoc->getLineNumber() && i < lines.size(); i++) { annotation.startPos += lines[i].size(); } annotation.startPos += loc->getColumnNumber() - sigLoc->getColumnNumber(); - for (size_t i = 0; i < loc->getEndLocation()->getLineNumber() - sigLoc->getLineNumber(); i++) + for (size_t i = 0; i < loc->getEndLocation()->getLineNumber() - sigLoc->getLineNumber() && i < lines.size(); i++) { annotation.endPos += lines[i].size(); } @@ -1983,6 +1994,7 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no // store texts of annotations std::vector> annotatedTexts; + std::wstring delimiter = nameDelimiterTypeToString(nameHierarchy.getDelimiter()); size_t offset = 0; for (const Annotation& annotation : annotations) { @@ -1991,8 +2003,12 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no annotation.endPos - annotation.startPos + 1 ); + // only replace name if not already prepended with other qualifiers + size_t delimiterPos = code.rfind(delimiter, annotation.startPos); + // if is function name itself, replace with qualified name if (utility::containsElement(file->getSourceLocationById(annotation.locationId)->getTokenIds(), node.id) && + (delimiterPos == std::wstring::npos || delimiterPos < annotation.startPos - delimiter.size()) && text.size() <= nameHierarchy.getRawName().size()) { std::wstring name = nameHierarchy.getQualifiedName(); @@ -2033,7 +2049,6 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no return snippet; } - // otherwise augment the name with signature with locations for type usages snippet.code = utility::breakSignature( nameHierarchy.getSignature().getPrefix(), diff --git a/src/lib_utility/utility/utilityString.cpp b/src/lib_utility/utility/utilityString.cpp index eae7d80d..5c5703b8 100644 --- a/src/lib_utility/utility/utilityString.cpp +++ b/src/lib_utility/utility/utilityString.cpp @@ -396,7 +396,26 @@ namespace utility namePart.pop_back(); } - size_t splitPos = namePart.rfind(L' '); + size_t splitPos = std::wstring::npos; + parenCount = 0; + for (size_t i = namePart.size(); i > 0; i--) + { + const wchar_t c = namePart[i]; + if (c == L'>' || c == L')') + { + parenCount++; + } + else if (c == L'<' || c == L'(') + { + parenCount--; + } + else if (!parenCount && c == L' ') + { + splitPos = i; + break; + } + } + if (splitPos != std::wstring::npos) { returnPart = namePart.substr(0, splitPos);