data: readded signature distinction for functions
This commit is contained in:
@@ -1,12 +1,26 @@
|
||||
|
||||
int number = 3;
|
||||
|
||||
int calculate();
|
||||
|
||||
int calculate(long i)
|
||||
{
|
||||
int a = 1 + 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
int calculate()
|
||||
{
|
||||
int a = 1 + 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
int calculate(int i)
|
||||
{
|
||||
int a = 1 + 2;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
int count = 0;
|
||||
|
||||
|
||||
@@ -115,8 +115,6 @@ add_files(
|
||||
data/graph/token_component/TokenComponentFilePath.h
|
||||
data/graph/token_component/TokenComponentName.cpp
|
||||
data/graph/token_component/TokenComponentName.h
|
||||
data/graph/token_component/TokenComponentSignature.cpp
|
||||
data/graph/token_component/TokenComponentSignature.h
|
||||
data/graph/token_component/TokenComponentStatic.cpp
|
||||
data/graph/token_component/TokenComponentStatic.h
|
||||
|
||||
|
||||
@@ -99,22 +99,22 @@ int SqliteStorage::addSourceLocation(Id elementId, Id fileNodeId, uint startLine
|
||||
return m_database.lastRowId();
|
||||
}
|
||||
|
||||
Id SqliteStorage::addNameHierarchyElement(const std::string& name)
|
||||
{
|
||||
m_database.execDML((
|
||||
"INSERT INTO name_hierarchy_element(id, name, parent_id) "
|
||||
"VALUES(NULL, '" + name + "', NULL);"
|
||||
).c_str());
|
||||
|
||||
return m_database.lastRowId();
|
||||
}
|
||||
|
||||
Id SqliteStorage::addNameHierarchyElement(const std::string& name, Id parentId)
|
||||
{
|
||||
m_database.execDML((
|
||||
"INSERT INTO name_hierarchy_element(id, name, parent_id) "
|
||||
"VALUES (NULL, '" + name + "', " + std::to_string(parentId) + ");"
|
||||
).c_str());
|
||||
if (parentId)
|
||||
{
|
||||
m_database.execDML((
|
||||
"INSERT INTO name_hierarchy_element(id, name, parent_id) "
|
||||
"VALUES (NULL, '" + name + "', " + std::to_string(parentId) + ");"
|
||||
).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_database.execDML((
|
||||
"INSERT INTO name_hierarchy_element(id, name, parent_id) "
|
||||
"VALUES(NULL, '" + name + "', NULL);"
|
||||
).c_str());
|
||||
}
|
||||
|
||||
return m_database.lastRowId();
|
||||
}
|
||||
@@ -123,7 +123,17 @@ Id SqliteStorage::addComponentAccess(Id memberEdgeId, int type)
|
||||
{
|
||||
m_database.execDML((
|
||||
"INSERT INTO component_access(id, edge_id, type) "
|
||||
"VALUES (NULL, '" + std::to_string(memberEdgeId) + "', " + std::to_string(type) + ");"
|
||||
"VALUES (NULL, " + std::to_string(memberEdgeId) + ", " + std::to_string(type) + ");"
|
||||
).c_str());
|
||||
|
||||
return m_database.lastRowId();
|
||||
}
|
||||
|
||||
Id SqliteStorage::addSignature(Id nodeId, const std::string& signature)
|
||||
{
|
||||
m_database.execDML((
|
||||
"INSERT INTO function_signature(id, signature) "
|
||||
"VALUES (" + std::to_string(nodeId) + ", '" + signature + "');"
|
||||
).c_str());
|
||||
|
||||
return m_database.lastRowId();
|
||||
@@ -454,18 +464,20 @@ void SqliteStorage::setNodeType(int type, Id nodeId)
|
||||
).c_str());
|
||||
}
|
||||
|
||||
Id SqliteStorage::getNameHierarchyElementIdByName(const std::string& name) const
|
||||
{
|
||||
return getFirstResult<Id>(
|
||||
"SELECT id FROM name_hierarchy_element WHERE name == '" + name + "';"
|
||||
);
|
||||
}
|
||||
|
||||
Id SqliteStorage::getNameHierarchyElementIdByName(const std::string& name, Id parentId) const
|
||||
{
|
||||
return getFirstResult<Id>(
|
||||
"SELECT id FROM name_hierarchy_element WHERE name == '" + name + "' AND parent_id == " + std::to_string(parentId) + ";"
|
||||
);
|
||||
if (parentId)
|
||||
{
|
||||
return getFirstResult<Id>(
|
||||
"SELECT id FROM name_hierarchy_element WHERE name == '" + name + "' AND parent_id == " + std::to_string(parentId) + ";"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return getFirstResult<Id>(
|
||||
"SELECT id FROM name_hierarchy_element WHERE name == '" + name + "';"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Id SqliteStorage::getNameHierarchyElementIdByNodeId(const Id nodeId) const
|
||||
@@ -623,6 +635,20 @@ StorageComponentAccess SqliteStorage::getComponentAccessByMemberEdgeId(Id member
|
||||
return StorageComponentAccess(0, 0, 0);
|
||||
}
|
||||
|
||||
Id SqliteStorage::getNodeIdBySignature(const std::string& signature) const
|
||||
{
|
||||
CppSQLite3Query q = m_database.execQuery((
|
||||
"SELECT id, signature FROM function_signature WHERE signature == '" + signature + "';"
|
||||
).c_str());
|
||||
|
||||
while (!q.eof())
|
||||
{
|
||||
return q.getIntField(0, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SqliteStorage::getNodeCount() const
|
||||
{
|
||||
return m_database.execScalar("SELECT COUNT(*) from node;");
|
||||
@@ -640,6 +666,8 @@ int SqliteStorage::getNameHierarchyElementCount() const
|
||||
|
||||
void SqliteStorage::clearTables()
|
||||
{
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.function_signature;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.component_access;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.source_location;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.name_hierarchy_element;");
|
||||
m_database.execDML("DROP TABLE IF EXISTS main.file;");
|
||||
@@ -719,6 +747,14 @@ void SqliteStorage::setupTables()
|
||||
"PRIMARY KEY(id), "
|
||||
"FOREIGN KEY(edge_id) REFERENCES edge(id) ON DELETE CASCADE);"
|
||||
);
|
||||
|
||||
m_database.execDML(
|
||||
"CREATE TABLE IF NOT EXISTS function_signature("
|
||||
"id INTEGER NOT NULL, "
|
||||
"signature TEXT, "
|
||||
"PRIMARY KEY(id), "
|
||||
"FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE);"
|
||||
);
|
||||
}
|
||||
|
||||
StorageFile SqliteStorage::getFirstFile(const std::string& query) const
|
||||
|
||||
@@ -31,9 +31,10 @@ public:
|
||||
Id addNode(int type, Id nameId);
|
||||
Id addFile(Id nameId, const std::string& filePath, const std::string& modificationTime);
|
||||
int addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope);
|
||||
Id addNameHierarchyElement(const std::string& name);
|
||||
Id addNameHierarchyElement(const std::string& name, Id parentId);
|
||||
Id addNameHierarchyElement(const std::string& name, Id parentId = 0);
|
||||
|
||||
Id addComponentAccess(Id memberEdgeId, int type);
|
||||
Id addSignature(Id nodeId, const std::string& signature);
|
||||
|
||||
void removeElement(Id id);
|
||||
void removeNameHierarchyElement(Id id);
|
||||
@@ -65,9 +66,7 @@ public:
|
||||
|
||||
void setNodeType(int type, Id nodeId);
|
||||
|
||||
Id getNameHierarchyElementIdByName(const std::string& name) const;
|
||||
Id getNameHierarchyElementIdByName(const std::string& name, Id parentId) const;
|
||||
|
||||
Id getNameHierarchyElementIdByName(const std::string& name, Id parentId = 0) const;
|
||||
Id getNameHierarchyElementIdByNodeId(const Id nodeId) const;
|
||||
|
||||
std::vector<StorageNameHierarchyElement> getAllNameHierarchyElements() const;
|
||||
@@ -82,6 +81,7 @@ public:
|
||||
Id getElementIdByLocationId(Id locationId) const;
|
||||
|
||||
StorageComponentAccess getComponentAccessByMemberEdgeId(Id memberEdgeId) const;
|
||||
Id getNodeIdBySignature(const std::string& signature) const;
|
||||
|
||||
int getNodeCount() const;
|
||||
int getEdgeCount() const;
|
||||
|
||||
+28
-35
@@ -1059,7 +1059,7 @@ const SearchIndex& Storage::getSearchIndex() const
|
||||
return m_tokenIndex;
|
||||
}
|
||||
|
||||
Id Storage::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy)
|
||||
Id Storage::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool distinct)
|
||||
{
|
||||
addNameHierarchyElements(nameHierarchy);
|
||||
|
||||
@@ -1067,32 +1067,26 @@ Id Storage::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarch
|
||||
Id parentNodeId = 0;
|
||||
for (size_t i = 0; i < nameHierarchy.size(); i++)
|
||||
{
|
||||
Node::NodeType type = (i == nameHierarchy.size() - 1 ? nodeType : Node::NODE_UNDEFINED);
|
||||
bool lastName = (i == nameHierarchy.size() - 1);
|
||||
|
||||
Id nameHierarchyElementId = 0;
|
||||
if (parentNameHierarchyElementId == 0)
|
||||
{
|
||||
nameHierarchyElementId = m_sqliteStorage.getNameHierarchyElementIdByName(nameHierarchy[i]->getFullName());
|
||||
}
|
||||
else
|
||||
{
|
||||
nameHierarchyElementId =
|
||||
m_sqliteStorage.getNameHierarchyElementIdByName(nameHierarchy[i]->getFullName(), parentNameHierarchyElementId);
|
||||
}
|
||||
Node::NodeType type = (lastName ? nodeType : Node::NODE_UNDEFINED);
|
||||
|
||||
Id nameHierarchyElementId =
|
||||
m_sqliteStorage.getNameHierarchyElementIdByName(nameHierarchy[i]->getFullName(), parentNameHierarchyElementId);
|
||||
|
||||
const StorageNode node = m_sqliteStorage.getNodeByNameId(nameHierarchyElementId);
|
||||
Id nodeId = node.id;
|
||||
|
||||
if (nodeId == 0)
|
||||
if (nodeId == 0 || (lastName && distinct))
|
||||
{
|
||||
nodeId = m_sqliteStorage.addNode(Node::typeToInt(type), nameHierarchyElementId);
|
||||
|
||||
if (parentNodeId != 0) // TODO: maybe check if this edge exists in general and create it if not.
|
||||
if (parentNodeId != 0)
|
||||
{
|
||||
m_sqliteStorage.addEdge(Edge::EDGE_MEMBER, parentNodeId, nodeId);
|
||||
addEdge(parentNodeId, nodeId, Edge::EDGE_MEMBER);
|
||||
}
|
||||
}
|
||||
else if (i == nameHierarchy.size() - 1) // we only know the type of the last node that will be added.
|
||||
else if (lastName) // Update the type of the last node if the new type is more specific.
|
||||
{
|
||||
Node::NodeType storedType = Node::intToType(node.type);
|
||||
if (type > storedType)
|
||||
@@ -1110,13 +1104,16 @@ Id Storage::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarch
|
||||
|
||||
Id Storage::addNodeHierarchyWithDistinctSignature(Node::NodeType type, const ParseFunction& function)
|
||||
{
|
||||
return addNodeHierarchy(type, function.nameHierarchy);
|
||||
std::string signature = ParserClient::functionSignatureStr(function);
|
||||
Id nodeId = m_sqliteStorage.getNodeIdBySignature(signature);
|
||||
|
||||
//// TODO: Instead of saving the whole signature string, the signature should be just a set of wordIds.
|
||||
//Id signatureId = m_tokenIndex.getWordId(ParserClient::functionSignatureStr(function));
|
||||
//std::shared_ptr<TokenComponentSignature> signature = std::make_shared<TokenComponentSignature>(signatureId);
|
||||
if (!nodeId)
|
||||
{
|
||||
nodeId = addNodeHierarchy(type, function.nameHierarchy, true);
|
||||
m_sqliteStorage.addSignature(nodeId, signature);
|
||||
}
|
||||
|
||||
//return m_graph.createNodeHierarchyWithDistinctSignature(type, searchNode, signature);
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
Id Storage::addNameHierarchyElements(NameHierarchy nameHierarchy)
|
||||
@@ -1131,14 +1128,7 @@ Id Storage::addNameHierarchyElements(NameHierarchy nameHierarchy)
|
||||
|
||||
if (nodeMayExist)
|
||||
{
|
||||
if (parentId == 0)
|
||||
{
|
||||
nodeId = m_sqliteStorage.getNameHierarchyElementIdByName(elementName);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeId = m_sqliteStorage.getNameHierarchyElementIdByName(elementName, parentId);
|
||||
}
|
||||
nodeId = m_sqliteStorage.getNameHierarchyElementIdByName(elementName, parentId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1147,11 +1137,7 @@ Id Storage::addNameHierarchyElements(NameHierarchy nameHierarchy)
|
||||
|
||||
if (nodeId == 0)
|
||||
{
|
||||
if (parentId == 0)
|
||||
nodeId = m_sqliteStorage.addNameHierarchyElement(elementName);
|
||||
else
|
||||
nodeId = m_sqliteStorage.addNameHierarchyElement(elementName, parentId);
|
||||
|
||||
nodeId = m_sqliteStorage.addNameHierarchyElement(elementName, parentId);
|
||||
nodeMayExist = false;
|
||||
}
|
||||
|
||||
@@ -1184,7 +1170,7 @@ int Storage::addSourceLocation(int elementNodeId, const ParseLocation& location,
|
||||
}
|
||||
}
|
||||
|
||||
Id Storage::addEdge(Id sourceNodeId, Id targetNodeId, Edge::EdgeType type, ParseLocation location)
|
||||
Id Storage::addEdge(Id sourceNodeId, Id targetNodeId, Edge::EdgeType type)
|
||||
{
|
||||
Id edgeId = m_sqliteStorage.getEdgeBySourceTargetType(sourceNodeId, targetNodeId, type).id;
|
||||
|
||||
@@ -1193,6 +1179,13 @@ Id Storage::addEdge(Id sourceNodeId, Id targetNodeId, Edge::EdgeType type, Parse
|
||||
edgeId = m_sqliteStorage.addEdge(type, sourceNodeId, targetNodeId);
|
||||
}
|
||||
|
||||
return edgeId;
|
||||
}
|
||||
|
||||
Id Storage::addEdge(Id sourceNodeId, Id targetNodeId, Edge::EdgeType type, ParseLocation location)
|
||||
{
|
||||
Id edgeId = addEdge(sourceNodeId, targetNodeId, type);
|
||||
|
||||
addSourceLocation(edgeId, location, false);
|
||||
|
||||
return edgeId;
|
||||
|
||||
@@ -151,10 +151,12 @@ public:
|
||||
const SearchIndex& getSearchIndex() const;
|
||||
|
||||
private:
|
||||
Id addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy);
|
||||
Id addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, bool distinct = false);
|
||||
Id addNodeHierarchyWithDistinctSignature(Node::NodeType type, const ParseFunction& function);
|
||||
Id addNameHierarchyElements(NameHierarchy nameHierarchy);
|
||||
int addSourceLocation(int elementNodeId, const ParseLocation& location, bool isScope = false);
|
||||
|
||||
Id addEdge(Id sourceNodeId, Id targetNodeId, Edge::EdgeType type);
|
||||
Id addEdge(Id sourceNodeId, Id targetNodeId, Edge::EdgeType type, ParseLocation location);
|
||||
|
||||
Id getFileNodeId(const FilePath& filePath);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "data/graph/token_component/TokenComponentConst.h"
|
||||
#include "data/graph/token_component/TokenComponentName.h"
|
||||
#include "data/graph/token_component/TokenComponentStatic.h"
|
||||
#include "data/graph/token_component/TokenComponentSignature.h"
|
||||
#include "data/graph/token_component/TokenComponentFilePath.h"
|
||||
|
||||
const Node::NodeTypeMask Node::NODE_NOT_VISIBLE = Node::NODE_UNDEFINED | Node::NODE_NAMESPACE;
|
||||
@@ -385,22 +384,6 @@ void Node::addComponentStatic(std::shared_ptr<TokenComponentStatic> component)
|
||||
}
|
||||
}
|
||||
|
||||
void Node::addComponentSignature(std::shared_ptr<TokenComponentSignature> component)
|
||||
{
|
||||
if (getComponent<TokenComponentSignature>())
|
||||
{
|
||||
LOG_ERROR("TokenComponentSignature has been set before!");
|
||||
}
|
||||
else if (!isType(NODE_UNDEFINED_FUNCTION | NODE_FUNCTION | NODE_METHOD))
|
||||
{
|
||||
LOG_ERROR("TokenComponentSignature can't be set on node of type: " + getTypeString());
|
||||
}
|
||||
else
|
||||
{
|
||||
addComponent(component);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::addComponentFilePath(std::shared_ptr<TokenComponentFilePath> component)
|
||||
{
|
||||
if (getComponent<TokenComponentFilePath>())
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#include "data/graph/token_component/TokenComponentSignature.h"
|
||||
|
||||
TokenComponentSignature::TokenComponentSignature(Id wordId)
|
||||
: m_wordId(wordId)
|
||||
{
|
||||
}
|
||||
|
||||
TokenComponentSignature::~TokenComponentSignature()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenComponent> TokenComponentSignature::copy() const
|
||||
{
|
||||
return std::make_shared<TokenComponentSignature>(*this);
|
||||
}
|
||||
|
||||
Id TokenComponentSignature::getWordId() const
|
||||
{
|
||||
return m_wordId;
|
||||
}
|
||||
|
||||
bool TokenComponentSignature::operator==(const TokenComponentSignature& other) const
|
||||
{
|
||||
return m_wordId == other.m_wordId;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef TOKEN_COMPONENT_SIGNATURE_H
|
||||
#define TOKEN_COMPONENT_SIGNATURE_H
|
||||
|
||||
#include "data/graph/token_component/TokenComponent.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class TokenComponentSignature
|
||||
: public TokenComponent
|
||||
{
|
||||
public:
|
||||
TokenComponentSignature(Id wordId);
|
||||
virtual ~TokenComponentSignature();
|
||||
|
||||
virtual std::shared_ptr<TokenComponent> copy() const;
|
||||
|
||||
Id getWordId() const;
|
||||
|
||||
bool operator==(const TokenComponentSignature& other) const;
|
||||
|
||||
private:
|
||||
const Id m_wordId;
|
||||
};
|
||||
|
||||
#endif // TOKEN_COMPONENT_SIGNATURE_H
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "data/graph/token_component/TokenComponentAbstraction.h"
|
||||
#include "data/graph/token_component/TokenComponentAccess.h"
|
||||
#include "data/graph/token_component/TokenComponentSignature.h"
|
||||
#include "data/graph/token_component/TokenComponentStatic.h"
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/parser/ParseFunction.h"
|
||||
@@ -141,15 +140,14 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(storage.getNameForNodeWithId(id), "isTrue");
|
||||
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_FUNCTION);
|
||||
//TS_ASSERT(node->getComponent<TokenComponentSignature>());
|
||||
//TS_ASSERT_EQUALS(storage.getWord(node->getComponent<TokenComponentSignature>()->getWordId()), "isTrue(char)");
|
||||
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_RETURN_TYPE_OF) + ":isTrue->bool") != 0);
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_PARAMETER_TYPE_OF) + ":isTrue->char") != 0);
|
||||
// TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_RETURN_TYPE_OF) + ":isTrue->bool") != 0);
|
||||
// TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_PARAMETER_TYPE_OF) + ":isTrue->char") != 0);
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_TYPE_USAGE) + ":isTrue->bool") != 0);
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_TYPE_USAGE) + ":isTrue->char") != 0);
|
||||
|
||||
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
|
||||
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
|
||||
TS_ASSERT_EQUALS(tlc->getTokenLocations().find(4)->second->getType(), TokenLocation::LOCATION_SCOPE);
|
||||
}
|
||||
|
||||
void test_storage_saves_method()
|
||||
@@ -165,11 +163,11 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(storage.getNameForNodeWithId(id), "isMethod");
|
||||
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(id), Node::NODE_METHOD);
|
||||
//TS_ASSERT(node->getComponent<TokenComponentSignature>());
|
||||
//TS_ASSERT_EQUALS(storage.getWord(node->getComponent<TokenComponentSignature>()->getWordId()), "isMethod(bool)");
|
||||
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_RETURN_TYPE_OF) + ":isMethod->void") != 0);
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_PARAMETER_TYPE_OF) + ":isMethod->bool") != 0);
|
||||
// TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_RETURN_TYPE_OF) + ":isMethod->void") != 0);
|
||||
// TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_PARAMETER_TYPE_OF) + ":isMethod->bool") != 0);
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_TYPE_USAGE) + ":isMethod->void") != 0);
|
||||
TS_ASSERT(storage.getIdForEdgeWithName(Edge::getTypeString(Edge::EDGE_TYPE_USAGE) + ":isMethod->bool") != 0);
|
||||
|
||||
std::shared_ptr<TokenLocationCollection> tlc = storage.getLocationCollectionForTokenId(id);
|
||||
TS_ASSERT_EQUALS(tlc->getTokenLocationCount(), 2);
|
||||
|
||||
Reference in New Issue
Block a user