logic: fixed bug where anonymous symbols were only partly named like the enclosing typedef
* removed post processing for anonymous typedefs. The storage transformation did not work in cases where the typedef is recorded in a previously indexed header. No type information was recorded while indexing the header a second time. But this type information would have been required by the transformation.
This commit is contained in:
@@ -24,16 +24,6 @@ Settings.cpp WARNING: File for Settings not found: data/SettingsTestSuite/wrong_
|
||||
SourceLocationCollection.cpp ERROR: SourceLocation has wrong boundaries: file.c 2:3 2:1
|
||||
SourceLocationCollection.cpp ERROR: SourceLocation has wrong boundaries: file.c 4:1 1:10
|
||||
TextAccess.cpp ERROR: Could not open file path/to/test.h
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Applying storage transformation to rename anonymous types inside typedefs.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Renamed 1 types.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Applying storage transformation to rename anonymous types inside typedefs.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Renamed 1 types.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Applying storage transformation to rename anonymous types inside typedefs.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Renamed 1 types.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Applying storage transformation to rename anonymous types inside typedefs.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Renamed 1 types.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Applying storage transformation to rename anonymous types inside typedefs.
|
||||
StorageTransformationAnonymousTypedef.cpp INFO: Renamed 0 types.
|
||||
TextAccess.cpp WARNING: Index 'firstLine' has to be lower or equal index 'lastLine', is 3 > 2
|
||||
TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8
|
||||
TextAccess.cpp WARNING: Tried to access index 10. Maximum index is 8
|
||||
|
||||
@@ -21,7 +21,6 @@ void SharedIndexerCommand::fromLocal(IndexerCommand* indexerCommand)
|
||||
setCompilerFlags(cmd->getCompilerFlags());
|
||||
setSystemHeaderSearchPaths(cmd->getSystemHeaderSearchPaths());
|
||||
setFrameworkSearchhPaths(cmd->getFrameworkSearchPaths());
|
||||
setShouldApplyAnonymousTypedefTransformation(cmd->shouldApplyAnonymousTypedefTransformation());
|
||||
}
|
||||
else if (dynamic_cast<IndexerCommandCxxManual*>(indexerCommand) != NULL)
|
||||
{
|
||||
@@ -32,7 +31,6 @@ void SharedIndexerCommand::fromLocal(IndexerCommand* indexerCommand)
|
||||
setCompilerFlags(cmd->getCompilerFlags());
|
||||
setSystemHeaderSearchPaths(cmd->getSystemHeaderSearchPaths());
|
||||
setFrameworkSearchhPaths(cmd->getFrameworkSearchPaths());
|
||||
setShouldApplyAnonymousTypedefTransformation(cmd->shouldApplyAnonymousTypedefTransformation());
|
||||
}
|
||||
else if (dynamic_cast<IndexerCommandJava*>(indexerCommand) != NULL)
|
||||
{
|
||||
@@ -61,8 +59,7 @@ std::shared_ptr<IndexerCommand> SharedIndexerCommand::fromShared(const SharedInd
|
||||
indexerCommand.getWorkingDirectory(),
|
||||
indexerCommand.getCompilerFlags(),
|
||||
indexerCommand.getSystemHeaderSearchPaths(),
|
||||
indexerCommand.getFrameworkSearchhPaths(),
|
||||
indexerCommand.shouldApplyAnonymousTypedefTransformation()
|
||||
indexerCommand.getFrameworkSearchhPaths()
|
||||
);
|
||||
return command;
|
||||
}
|
||||
@@ -75,8 +72,7 @@ std::shared_ptr<IndexerCommand> SharedIndexerCommand::fromShared(const SharedInd
|
||||
indexerCommand.getLanguageStandard(),
|
||||
indexerCommand.getSystemHeaderSearchPaths(),
|
||||
indexerCommand.getFrameworkSearchhPaths(),
|
||||
indexerCommand.getCompilerFlags(),
|
||||
indexerCommand.shouldApplyAnonymousTypedefTransformation()
|
||||
indexerCommand.getCompilerFlags()
|
||||
);
|
||||
return command;
|
||||
}
|
||||
@@ -274,16 +270,6 @@ void SharedIndexerCommand::setFrameworkSearchhPaths(const std::vector<FilePath>&
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedIndexerCommand::shouldApplyAnonymousTypedefTransformation() const
|
||||
{
|
||||
return m_shouldApplyAnonymousTypedefTransformation;
|
||||
}
|
||||
|
||||
void SharedIndexerCommand::setShouldApplyAnonymousTypedefTransformation(bool shouldApplyAnonymousTypedefTransformation)
|
||||
{
|
||||
m_shouldApplyAnonymousTypedefTransformation = shouldApplyAnonymousTypedefTransformation;
|
||||
}
|
||||
|
||||
std::vector<FilePath> SharedIndexerCommand::getClassPaths() const
|
||||
{
|
||||
std::vector<FilePath> result;
|
||||
|
||||
@@ -41,9 +41,6 @@ public:
|
||||
std::vector<FilePath> getFrameworkSearchhPaths() const;
|
||||
void setFrameworkSearchhPaths(const std::vector<FilePath>& searchPaths);
|
||||
|
||||
bool shouldApplyAnonymousTypedefTransformation() const;
|
||||
void setShouldApplyAnonymousTypedefTransformation(bool shouldApplyAnonymousTypedefTransformation);
|
||||
|
||||
std::vector<FilePath> getClassPaths() const;
|
||||
void setClassPaths(const std::vector<FilePath>& classPaths);
|
||||
|
||||
@@ -72,7 +69,6 @@ private:
|
||||
SharedMemory::Vector<SharedMemory::String> m_compilerFlags;
|
||||
SharedMemory::Vector<SharedMemory::String> m_systemHeaderSearchPaths;
|
||||
SharedMemory::Vector<SharedMemory::String> m_frameworkSearchPaths;
|
||||
bool m_shouldApplyAnonymousTypedefTransformation;
|
||||
|
||||
// java
|
||||
SharedMemory::Vector<SharedMemory::String> m_classPaths;
|
||||
|
||||
@@ -8,7 +8,6 @@ SourceGroupSettingsCxx::SourceGroupSettingsCxx(const std::string& id, SourceGrou
|
||||
, m_headerSearchPaths(std::vector<FilePath>())
|
||||
, m_frameworkSearchPaths(std::vector<FilePath>())
|
||||
, m_compilerFlags(std::vector<std::string>())
|
||||
, m_shouldApplyAnonymousTypedefTransformation(true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,7 +24,6 @@ void SourceGroupSettingsCxx::load(std::shared_ptr<const ConfigManager> config)
|
||||
setHeaderSearchPaths(getPathValues(key + "/header_search_paths/header_search_path", config));
|
||||
setFrameworkSearchPaths(getPathValues(key + "/framework_search_paths/framework_search_path", config));
|
||||
setCompilerFlags(getValues<std::string>(key + "/compiler_flags/compiler_flag", std::vector<std::string>(), config));
|
||||
setShouldApplyAnonymousTypedefTransformation(getValue<bool>(key + "/should_apply_anonymous_typedef_transformation", true, config));
|
||||
}
|
||||
|
||||
void SourceGroupSettingsCxx::save(std::shared_ptr<ConfigManager> config)
|
||||
@@ -37,7 +35,6 @@ void SourceGroupSettingsCxx::save(std::shared_ptr<ConfigManager> config)
|
||||
setPathValues(key + "/header_search_paths/header_search_path", getHeaderSearchPaths(), config);
|
||||
setPathValues(key + "/framework_search_paths/framework_search_path", getFrameworkSearchPaths(), config);
|
||||
setValues(key + "/compiler_flags/compiler_flag", getCompilerFlags(), config);
|
||||
setValue(key + "/should_apply_anonymous_typedef_transformation", getShouldApplyAnonymousTypedefTransformation(), config);
|
||||
}
|
||||
|
||||
bool SourceGroupSettingsCxx::equals(std::shared_ptr<SourceGroupSettings> other) const
|
||||
@@ -146,16 +143,6 @@ void SourceGroupSettingsCxx::setCompilerFlags(const std::vector<std::string>& co
|
||||
m_compilerFlags = compilerFlags;
|
||||
}
|
||||
|
||||
bool SourceGroupSettingsCxx::getShouldApplyAnonymousTypedefTransformation() const
|
||||
{
|
||||
return m_shouldApplyAnonymousTypedefTransformation;
|
||||
}
|
||||
|
||||
void SourceGroupSettingsCxx::setShouldApplyAnonymousTypedefTransformation(bool shouldApplyAnonymousTypedefTransformation)
|
||||
{
|
||||
m_shouldApplyAnonymousTypedefTransformation = shouldApplyAnonymousTypedefTransformation;
|
||||
}
|
||||
|
||||
std::vector<std::string> SourceGroupSettingsCxx::getDefaultSourceExtensions() const
|
||||
{
|
||||
std::vector<std::string> defaultValues;
|
||||
|
||||
@@ -28,9 +28,6 @@ public:
|
||||
std::vector<std::string> getCompilerFlags() const;
|
||||
void setCompilerFlags(const std::vector<std::string>& compilerFlags);
|
||||
|
||||
bool getShouldApplyAnonymousTypedefTransformation() const;
|
||||
void setShouldApplyAnonymousTypedefTransformation(bool shouldApplyAnonymousTypedefTransformation);
|
||||
|
||||
private:
|
||||
virtual std::vector<std::string> getDefaultSourceExtensions() const;
|
||||
virtual std::string getDefaultStandard() const;
|
||||
@@ -38,7 +35,6 @@ private:
|
||||
std::vector<FilePath> m_headerSearchPaths;
|
||||
std::vector<FilePath> m_frameworkSearchPaths;
|
||||
std::vector<std::string> m_compilerFlags;
|
||||
bool m_shouldApplyAnonymousTypedefTransformation;
|
||||
};
|
||||
|
||||
#endif // SOURCE_GROUP_SETTINGS_CXX_H
|
||||
|
||||
@@ -77,9 +77,6 @@ add_files(
|
||||
data/parser/cxx/PreprocessorCallbacks.h
|
||||
data/parser/cxx/utilityClang.cpp
|
||||
data/parser/cxx/utilityClang.h
|
||||
|
||||
data/storage/StorageTransformationAnonymousTypedef.cpp
|
||||
data/storage/StorageTransformationAnonymousTypedef.h
|
||||
|
||||
project/IncludeDirective.cpp
|
||||
project/IncludeDirective.h
|
||||
|
||||
@@ -6,14 +6,12 @@ IndexerCommandCxx::IndexerCommandCxx(
|
||||
const std::set<FilePath>& excludedPaths,
|
||||
const std::vector<FilePath>& systemHeaderSearchPaths,
|
||||
const std::vector<FilePath>& frameworkSearchPaths,
|
||||
const std::vector<std::string>& compilerFlags,
|
||||
const bool shouldApplyAnonymousTypedefTransformation
|
||||
const std::vector<std::string>& compilerFlags
|
||||
)
|
||||
: IndexerCommand(sourceFilePath, indexedPaths, excludedPaths)
|
||||
, m_systemHeaderSearchPaths(systemHeaderSearchPaths)
|
||||
, m_frameworkSearchPaths(frameworkSearchPaths)
|
||||
, m_compilerFlags(compilerFlags)
|
||||
, m_shouldApplyAnonymousTypedefTransformation(shouldApplyAnonymousTypedefTransformation)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -57,8 +55,3 @@ std::vector<std::string> IndexerCommandCxx::getCompilerFlags() const
|
||||
{
|
||||
return m_compilerFlags;
|
||||
}
|
||||
|
||||
bool IndexerCommandCxx::shouldApplyAnonymousTypedefTransformation() const
|
||||
{
|
||||
return m_shouldApplyAnonymousTypedefTransformation;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ public:
|
||||
const std::set<FilePath>& excludedPaths,
|
||||
const std::vector<FilePath>& systemHeaderSearchPaths,
|
||||
const std::vector<FilePath>& frameworkSearchPaths,
|
||||
const std::vector<std::string>& compilerFlags,
|
||||
const bool shouldApplyAnonymousTypedefTransformation);
|
||||
const std::vector<std::string>& compilerFlags);
|
||||
|
||||
virtual ~IndexerCommandCxx();
|
||||
virtual size_t getByteSize(size_t stringSize) const override;
|
||||
@@ -28,13 +27,10 @@ public:
|
||||
std::vector<FilePath> getFrameworkSearchPaths() const;
|
||||
std::vector<std::string> getCompilerFlags() const;
|
||||
|
||||
bool shouldApplyAnonymousTypedefTransformation() const;
|
||||
|
||||
private:
|
||||
std::vector<FilePath> m_systemHeaderSearchPaths;
|
||||
std::vector<FilePath> m_frameworkSearchPaths;
|
||||
std::vector<std::string> m_compilerFlags;
|
||||
bool m_shouldApplyAnonymousTypedefTransformation;
|
||||
};
|
||||
|
||||
#endif // INDEXER_COMMAND_CXXL_H
|
||||
|
||||
@@ -46,10 +46,9 @@ IndexerCommandCxxCdb::IndexerCommandCxxCdb(
|
||||
const FilePath& workingDirectory,
|
||||
const std::vector<std::string>& compilerFlags,
|
||||
const std::vector<FilePath>& systemHeaderSearchPaths,
|
||||
const std::vector<FilePath>& frameworkSearchPaths,
|
||||
const bool shouldApplyAnonymousTypedefTransformation
|
||||
const std::vector<FilePath>& frameworkSearchPaths
|
||||
)
|
||||
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags, shouldApplyAnonymousTypedefTransformation)
|
||||
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags)
|
||||
, m_workingDirectory(workingDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,8 +27,7 @@ public:
|
||||
const FilePath& workingDirectory,
|
||||
const std::vector<std::string>& compilerFlags,
|
||||
const std::vector<FilePath>& systemHeaderSearchPaths,
|
||||
const std::vector<FilePath>& frameworkSearchPaths,
|
||||
const bool shouldApplyAnonymousTypedefTransformation);
|
||||
const std::vector<FilePath>& frameworkSearchPaths);
|
||||
|
||||
virtual ~IndexerCommandCxxCdb();
|
||||
|
||||
|
||||
@@ -12,10 +12,9 @@ IndexerCommandCxxManual::IndexerCommandCxxManual(
|
||||
const std::string& languageStandard,
|
||||
const std::vector<FilePath>& systemHeaderSearchPaths,
|
||||
const std::vector<FilePath>& frameworkSearchPaths,
|
||||
const std::vector<std::string>& compilerFlags,
|
||||
const bool shouldApplyAnonymousTypedefTransformation
|
||||
const std::vector<std::string>& compilerFlags
|
||||
)
|
||||
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags, shouldApplyAnonymousTypedefTransformation)
|
||||
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags)
|
||||
, m_languageStandard(languageStandard)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ public:
|
||||
const std::string& languageStandard,
|
||||
const std::vector<FilePath>& systemHeaderSearchPaths,
|
||||
const std::vector<FilePath>& frameworkSearchPaths,
|
||||
const std::vector<std::string>& compilerFlags,
|
||||
const bool shouldApplyAnonymousTypedefTransformation);
|
||||
const std::vector<std::string>& compilerFlags);
|
||||
|
||||
virtual ~IndexerCommandCxxManual();
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "data/indexer/Indexer.h"
|
||||
#include "data/parser/ParserClientImpl.h"
|
||||
#include "data/storage/StorageTransformationAnonymousTypedef.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
template <typename IndexerCommandType, typename ParserType>
|
||||
@@ -55,11 +54,6 @@ std::shared_ptr<IntermediateStorage> IndexerCxx<IndexerCommandType, ParserType>:
|
||||
return std::shared_ptr<IntermediateStorage>();
|
||||
}
|
||||
|
||||
if (indexerCommand->shouldApplyAnonymousTypedefTransformation())
|
||||
{
|
||||
StorageTransformationAnonymousTypedef::transform(storage);
|
||||
}
|
||||
|
||||
return storage;
|
||||
}
|
||||
|
||||
|
||||
@@ -194,7 +194,6 @@ void CxxAstVisitorComponentIndexer::visitTagDecl(clang::TagDecl* d)
|
||||
symbolKind
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +440,7 @@ void CxxAstVisitorComponentIndexer::visitTypedefDecl(clang::TypedefDecl* d)
|
||||
{
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(d),
|
||||
SYMBOL_TYPEDEF,
|
||||
d->getAnonDeclWithTypedefName() == NULL ? SYMBOL_TYPEDEF : utility::convertTagKind(d->getAnonDeclWithTypedefName()->getTagKind()),
|
||||
getParseLocation(d->getLocation()),
|
||||
utility::convertAccessSpecifier(d->getAccess()),
|
||||
utility::isImplicit(d) ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT
|
||||
@@ -455,7 +454,7 @@ void CxxAstVisitorComponentIndexer::visitTypeAliasDecl(clang::TypeAliasDecl* d)
|
||||
{
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(d),
|
||||
SYMBOL_TYPEDEF,
|
||||
d->getAnonDeclWithTypedefName() == NULL ? SYMBOL_TYPEDEF : utility::convertTagKind(d->getAnonDeclWithTypedefName()->getTagKind()),
|
||||
getParseLocation(d->getLocation()),
|
||||
utility::convertAccessSpecifier(d->getAccess()),
|
||||
utility::isImplicit(d) ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT
|
||||
|
||||
@@ -171,6 +171,14 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
|
||||
ScopedSwitcher<const clang::NamedDecl*> switcher(m_currentDecl, declaration);
|
||||
|
||||
std::string declNameString = declaration->getNameAsString();
|
||||
if (const clang::TagDecl* tagDecl = clang::dyn_cast_or_null<clang::TagDecl>(declaration))
|
||||
{
|
||||
if (const clang::TypedefNameDecl* typedefNameDecl = tagDecl->getTypedefNameForAnonDecl())
|
||||
{
|
||||
declNameString = typedefNameDecl->getNameAsString();
|
||||
}
|
||||
}
|
||||
|
||||
if (const clang::TypeAliasDecl* typeAliasDecl = clang::dyn_cast_or_null<clang::TypeAliasDecl>(declaration))
|
||||
{
|
||||
clang::TypeAliasTemplateDecl* templatedDeclaration = typeAliasDecl->getDescribedAliasTemplate();
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
#include "data/storage/StorageTransformationAnonymousTypedef.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "data/graph/Node.h"
|
||||
#include "data/name/NameDelimiterType.h"
|
||||
#include "data/storage/IntermediateStorage.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
void StorageTransformationAnonymousTypedef::transform(std::shared_ptr<IntermediateStorage> storage)
|
||||
{
|
||||
LOG_INFO("Applying storage transformation to rename anonymous types inside typedefs.");
|
||||
|
||||
if (!storage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<StorageNode> nodes = storage->getStorageNodes();
|
||||
std::vector<StorageEdge> edges = storage->getStorageEdges();
|
||||
std::vector<StorageOccurrence> occurrences = storage->getStorageOccurrences();
|
||||
|
||||
std::map<Id, Id> nodesToMerge;
|
||||
std::map<std::string, std::string> nodesToRename;
|
||||
|
||||
{
|
||||
std::map<Id, StorageNode> typedefNodes;
|
||||
std::map<Id, StorageNode> anonymousTypeNodes;
|
||||
|
||||
for (const StorageNode& node : nodes)
|
||||
{
|
||||
const NodeType::Type nodeType = utility::intToType(node.type);
|
||||
if (nodeType & NodeType::NODE_TYPEDEF)
|
||||
{
|
||||
typedefNodes.insert(std::pair<Id, StorageNode>(node.id, node));
|
||||
}
|
||||
else if(nodeType & (NodeType::NODE_STRUCT | NodeType::NODE_CLASS | NodeType::NODE_ENUM | NodeType::NODE_UNION))
|
||||
{
|
||||
const NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName);
|
||||
if (nameHierarchy.back() && utility::isPrefix("anonymous ", nameHierarchy.back()->getName()))
|
||||
{
|
||||
anonymousTypeNodes.insert(std::pair<Id, StorageNode>(node.id, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const StorageEdge& edge : edges)
|
||||
{
|
||||
if (Edge::intToType(edge.type) & Edge::EDGE_TYPE_USAGE)
|
||||
{
|
||||
std::map<Id, StorageNode>::const_iterator itAnonymousTypeNodes = anonymousTypeNodes.find(edge.targetNodeId);
|
||||
if (itAnonymousTypeNodes != anonymousTypeNodes.end())
|
||||
{
|
||||
std::map<Id, StorageNode>::const_iterator itTypedefNodes = typedefNodes.find(edge.sourceNodeId);
|
||||
if (itTypedefNodes != typedefNodes.end())
|
||||
{
|
||||
nodesToMerge.insert(std::pair<Id, Id>(itTypedefNodes->first, itAnonymousTypeNodes->first));
|
||||
nodesToRename.insert(std::pair<std::string, std::string>(itAnonymousTypeNodes->second.serializedName, itTypedefNodes->second.serializedName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove typedef nodes that refer to anonymous types
|
||||
// and rename anonymous types to typedef name
|
||||
for (size_t i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
if (nodesToMerge.find(nodes[i].id) != nodesToMerge.end())
|
||||
{
|
||||
nodes.erase(nodes.begin() + i);
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::map<std::string, std::string>::const_iterator it = nodesToRename.begin(); it != nodesToRename.end(); it++)
|
||||
{
|
||||
if (utility::isPrefix(it->first, nodes[i].serializedName))
|
||||
{
|
||||
nodes[i].serializedName = it->second + nodes[i].serializedName.substr(it->first.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// redirect edges that pointed to removed nodes
|
||||
for (StorageEdge& edge : edges)
|
||||
{
|
||||
std::map<Id, Id>::const_iterator it = nodesToMerge.find(edge.targetNodeId);
|
||||
if (it != nodesToMerge.end())
|
||||
{
|
||||
edge.targetNodeId = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// relink source locations of removed nodes
|
||||
for (StorageOccurrence& occurrence : occurrences)
|
||||
{
|
||||
std::map<Id, Id>::const_iterator it = nodesToMerge.find(occurrence.elementId);
|
||||
if (it != nodesToMerge.end())
|
||||
{
|
||||
occurrence.elementId = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
storage->setStorageNodes(nodes);
|
||||
storage->setStorageEdges(edges);
|
||||
storage->setStorageOccurrences(occurrences);
|
||||
|
||||
LOG_INFO("Renamed " + std::to_string(nodesToRename.size()) + " types.");
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef STORAGE_TRANSFORMATION_ANONYMOUS_TYPEDEF_H
|
||||
#define STORAGE_TRANSFORMATION_ANONYMOUS_TYPEDEF_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
class IntermediateStorage;
|
||||
|
||||
class StorageTransformationAnonymousTypedef
|
||||
{
|
||||
public:
|
||||
static void transform(std::shared_ptr<IntermediateStorage> storage);
|
||||
};
|
||||
|
||||
#endif // STORAGE_TRANSFORMATION_ANONYMOUS_TYPEDEF_H
|
||||
@@ -118,8 +118,7 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxCdb::getIndexerComman
|
||||
FilePath(command.Directory),
|
||||
currentCompilerFlags,
|
||||
systemHeaderSearchPaths,
|
||||
frameworkSearchPaths,
|
||||
m_settings->getShouldApplyAnonymousTypedefTransformation()
|
||||
frameworkSearchPaths
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +65,7 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxEmpty::getIndexerComm
|
||||
m_settings->getStandard(),
|
||||
systemHeaderSearchPaths,
|
||||
frameworkSearchPaths,
|
||||
compilerFlags,
|
||||
m_settings->getShouldApplyAnonymousTypedefTransformation()
|
||||
compilerFlags
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ add_files(
|
||||
SqliteBookmarkStorageTestSuite.h
|
||||
SqliteIndexStorageTestSuite.h
|
||||
StorageTestSuite.h
|
||||
StorageTransformationAnonymousTypedefTestSuite.h
|
||||
TaskSchedulerTestSuite.h
|
||||
TextAccessTestSuite.h
|
||||
UtilityStringTestSuite.h
|
||||
|
||||
@@ -139,8 +139,7 @@ private:
|
||||
"c++1z",
|
||||
utility::concat(std::vector<FilePath> { projectDataSrcRoot }, ApplicationSettings::getInstance()->getHeaderSearchPathsExpanded()),
|
||||
ApplicationSettings::getInstance()->getFrameworkSearchPathsExpanded(),
|
||||
std::vector<std::string> { "--target=x86_64-pc-windows-msvc" },
|
||||
true
|
||||
std::vector<std::string> { "--target=x86_64-pc-windows-msvc" }
|
||||
);
|
||||
|
||||
parser.buildIndex(command);
|
||||
|
||||
@@ -314,7 +314,7 @@ public:
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"} Foo;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
@@ -328,11 +328,11 @@ public:
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"} Foo;\n"
|
||||
"};\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float x;\n"
|
||||
"} Bar;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->structs.size(), 2);
|
||||
@@ -347,7 +347,7 @@ public:
|
||||
"{\n"
|
||||
" int i;\n"
|
||||
" float f;\n"
|
||||
"} Foo;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
@@ -355,6 +355,144 @@ public:
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_struct_declared_inside_typedef()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"} Foo;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->structs, "Foo <1:9 <1:9 1:14> 4:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->structs, "Foo <4:3 4:5>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_class_declared_inside_typedef()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"typedef class\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"} Foo;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->classes, "Foo <1:9 <1:9 1:13> 4:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->classes, "Foo <4:3 4:5>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_enum_declared_inside_typedef()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"typedef enum\n"
|
||||
"{\n"
|
||||
" CONSTANT_1;\n"
|
||||
"} Foo;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->enums, "Foo <1:9 <1:9 1:12> 4:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->enums, "Foo <4:3 4:5>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_union_declared_inside_typedef()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"typedef union\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
" float y;\n"
|
||||
"} Foo;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->unions, "Foo <1:9 <1:9 1:13> 5:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->unions, "Foo <5:3 5:5>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_struct_declared_inside_type_alias()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"using Foo = struct\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->structs, "Foo <1:13 <1:13 1:18> 4:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->structs, "Foo <1:7 1:9>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_class_declared_inside_type_alias()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"using Foo = class\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->classes, "Foo <1:13 <1:13 1:17> 4:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->classes, "Foo <1:7 1:9>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_enum_declared_inside_type_alias()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"using Foo = enum\n"
|
||||
"{\n"
|
||||
" CONSTANT_1;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->enums, "Foo <1:13 <1:13 1:16> 4:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->enums, "Foo <1:7 1:9>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_name_of_anonymous_union_declared_inside_type_alias()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"using Foo = union\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
" float y;\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->unions, "Foo <1:13 <1:13 1:17> 5:1>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->unions, "Foo <1:7 1:9>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_enum_defined_in_global_namespace()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
@@ -423,7 +561,7 @@ public:
|
||||
|
||||
void test_cxx_parser_finds_type_alias_in_class()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"class Foo\n"
|
||||
"{\n"
|
||||
" using Bar = Foo;\n"
|
||||
@@ -3839,8 +3977,7 @@ public:
|
||||
"c++1z",
|
||||
std::vector<FilePath>(),
|
||||
std::vector<FilePath>(),
|
||||
std::vector<std::string>(),
|
||||
false
|
||||
std::vector<std::string>()
|
||||
);
|
||||
|
||||
std::shared_ptr<TestParserClient> client = std::make_shared<TestParserClient>();
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
#include "cxxtest/TestSuite.h"
|
||||
|
||||
#include "data/storage/StorageTransformationAnonymousTypedef.h"
|
||||
#include "data/storage/IntermediateStorage.h"
|
||||
#include "data/graph/Node.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
class StorageTransformationAnonymousTypedefTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_transformation_removes_anonymous_class_that_has_typedef()
|
||||
{
|
||||
std::shared_ptr<IntermediateStorage> storage = std::make_shared<IntermediateStorage>();
|
||||
|
||||
Id anonymousTypeId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_CLASS), NameHierarchy::serialize(NameHierarchy("anonymous class (input.cc<1:9>)", NAME_DELIMITER_CXX))));
|
||||
Id typedefId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(NameHierarchy("ClassTypedef", NAME_DELIMITER_CXX))));
|
||||
storage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_TYPE_USAGE), typedefId, anonymousTypeId));
|
||||
|
||||
StorageTransformationAnonymousTypedef::transform(storage);
|
||||
|
||||
const std::vector<StorageNode> nodes = storage->getStorageNodes();
|
||||
std::vector<std::string> nodeNames(nodes.size());
|
||||
std::transform(nodes.begin(), nodes.end(), nodeNames.begin(), [](const StorageNode& node)
|
||||
{
|
||||
return NameHierarchy::deserialize(node.serializedName).getQualifiedNameWithSignature();
|
||||
});
|
||||
|
||||
TS_ASSERT_EQUALS(1, nodeNames.size());
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
nodeNames, "ClassTypedef"
|
||||
));
|
||||
}
|
||||
|
||||
void test_transformation_redirects_incoming_edges_to_renamed_anonymous_class()
|
||||
{
|
||||
std::shared_ptr<IntermediateStorage> storage = std::make_shared<IntermediateStorage>();
|
||||
|
||||
Id anonymousTypeId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_CLASS), NameHierarchy::serialize(NameHierarchy("anonymous class (input.cc<1:9>)", NAME_DELIMITER_CXX))));
|
||||
Id typedefId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(NameHierarchy("ClassTypedef", NAME_DELIMITER_CXX))));
|
||||
storage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_TYPE_USAGE), typedefId, anonymousTypeId));
|
||||
storage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_TYPE_USAGE), 42, typedefId));
|
||||
|
||||
StorageTransformationAnonymousTypedef::transform(storage);
|
||||
|
||||
Id targetNodeId = 0;
|
||||
for (const StorageEdge& edge : storage->getStorageEdges())
|
||||
{
|
||||
if (edge.sourceNodeId == 42)
|
||||
{
|
||||
targetNodeId = edge.targetNodeId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string targetNodeName = "";
|
||||
for (const StorageNode& node : storage->getStorageNodes())
|
||||
{
|
||||
if (node.id == targetNodeId)
|
||||
{
|
||||
targetNodeName = NameHierarchy::deserialize(node.serializedName).getQualifiedNameWithSignature();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(targetNodeName, "ClassTypedef");
|
||||
}
|
||||
|
||||
void test_transformation_keeps_outgoing_edges_of_renamed_anonymous_class()
|
||||
{
|
||||
std::shared_ptr<IntermediateStorage> storage = std::make_shared<IntermediateStorage>();
|
||||
|
||||
Id anonymousTypeId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_CLASS), NameHierarchy::serialize(NameHierarchy("anonymous class (input.cc<1:9>)", NAME_DELIMITER_CXX))));
|
||||
Id typedefId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(NameHierarchy("ClassTypedef", NAME_DELIMITER_CXX))));
|
||||
storage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_TYPE_USAGE), typedefId, anonymousTypeId));
|
||||
storage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_TYPE_USAGE), anonymousTypeId, 42));
|
||||
|
||||
StorageTransformationAnonymousTypedef::transform(storage);
|
||||
|
||||
Id sourceNodeId = 0;
|
||||
for (const StorageEdge& edge : storage->getStorageEdges())
|
||||
{
|
||||
if (edge.targetNodeId == 42)
|
||||
{
|
||||
sourceNodeId = edge.sourceNodeId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string sourceNodeName = "";
|
||||
for (const StorageNode& node : storage->getStorageNodes())
|
||||
{
|
||||
if (node.id == sourceNodeId)
|
||||
{
|
||||
sourceNodeName = NameHierarchy::deserialize(node.serializedName).getQualifiedNameWithSignature();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(sourceNodeName, "ClassTypedef");
|
||||
}
|
||||
|
||||
void test_transformation_renames_child_node_of_anonymous_class()
|
||||
{
|
||||
std::shared_ptr<IntermediateStorage> storage = std::make_shared<IntermediateStorage>();
|
||||
|
||||
Id anonymousTypeId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_CLASS), NameHierarchy::serialize(NameHierarchy("anonymous class (input.cc<1:9>)", NAME_DELIMITER_CXX))));
|
||||
Id typedefId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(NameHierarchy("ClassTypedef", NAME_DELIMITER_CXX))));
|
||||
storage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_TYPE_USAGE), typedefId, anonymousTypeId));
|
||||
|
||||
Id anonymousTypeMemberId = storage->addNode(StorageNodeData(
|
||||
utility::nodeTypeToInt(NodeType::NODE_FIELD),
|
||||
NameHierarchy::serialize(NameHierarchy(utility::createVectorFromElements<std::string>("anonymous class (input.cc<1:9>)", "field"), NAME_DELIMITER_CXX))
|
||||
));
|
||||
|
||||
StorageTransformationAnonymousTypedef::transform(storage);
|
||||
|
||||
std::string memberNodeName = "";
|
||||
for (const StorageNode& node : storage->getStorageNodes())
|
||||
{
|
||||
if (node.id == anonymousTypeMemberId)
|
||||
{
|
||||
memberNodeName = NameHierarchy::deserialize(node.serializedName).getQualifiedNameWithSignature();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(memberNodeName, "ClassTypedef::field");
|
||||
}
|
||||
|
||||
void test_transformation_does_not_rename_named_class_with_typedef_in_anonymous_namespace()
|
||||
{
|
||||
std::shared_ptr<IntermediateStorage> storage = std::make_shared<IntermediateStorage>();
|
||||
|
||||
Id typeId = storage->addNode(StorageNodeData(
|
||||
utility::nodeTypeToInt(NodeType::NODE_CLASS),
|
||||
NameHierarchy::serialize(NameHierarchy(utility::createVectorFromElements<std::string>("anonymous namespace (input.cc<1:9>)", "Type"), NAME_DELIMITER_CXX))
|
||||
));
|
||||
Id typedefId = storage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(NameHierarchy("ClassTypedef", NAME_DELIMITER_CXX))));
|
||||
storage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_TYPE_USAGE), typedefId, typeId));
|
||||
|
||||
StorageTransformationAnonymousTypedef::transform(storage);
|
||||
|
||||
const std::vector<StorageNode> nodes = storage->getStorageNodes();
|
||||
std::vector<std::string> nodeNames(nodes.size());
|
||||
std::transform(nodes.begin(), nodes.end(), nodeNames.begin(), [](const StorageNode& node)
|
||||
{
|
||||
return NameHierarchy::deserialize(node.serializedName).getQualifiedNameWithSignature();
|
||||
});
|
||||
|
||||
TS_ASSERT_EQUALS(2, nodeNames.size());
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
nodeNames, "ClassTypedef"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
nodeNames, "anonymous namespace (input.cc<1:9>)::Type"
|
||||
));
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user