logic: name qualifiers of symbols are clickable now
This commit is contained in:
@@ -9,11 +9,11 @@ DefinitionKind intToDefinitionKind(int definitionKind)
|
||||
{
|
||||
switch (definitionKind)
|
||||
{
|
||||
case 0:
|
||||
case DEFINITION_NONE:
|
||||
return DEFINITION_NONE;
|
||||
case 1:
|
||||
case DEFINITION_IMPLICIT:
|
||||
return DEFINITION_IMPLICIT;
|
||||
case 2:
|
||||
case DEFINITION_EXPLICIT:
|
||||
return DEFINITION_EXPLICIT;
|
||||
}
|
||||
return DEFINITION_NONE;
|
||||
|
||||
@@ -2,38 +2,26 @@
|
||||
|
||||
int locationTypeToInt(LocationType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case LOCATION_TOKEN:
|
||||
return 0;
|
||||
case LOCATION_SCOPE:
|
||||
return 1;
|
||||
case LOCATION_LOCAL_SYMBOL:
|
||||
return 2;
|
||||
case LOCATION_ERROR:
|
||||
return 3;
|
||||
case LOCATION_FULLTEXT_SEARCH:
|
||||
return 4;
|
||||
case LOCATION_SCREEN_SEARCH:
|
||||
return 5;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
LocationType intToLocationType(int value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
case LOCATION_TOKEN:
|
||||
return LOCATION_TOKEN;
|
||||
case 1:
|
||||
case LOCATION_SCOPE:
|
||||
return LOCATION_SCOPE;
|
||||
case 2:
|
||||
case LOCATION_QUALIFIER:
|
||||
return LOCATION_QUALIFIER;
|
||||
case LOCATION_LOCAL_SYMBOL:
|
||||
return LOCATION_LOCAL_SYMBOL;
|
||||
case 3:
|
||||
return LOCATION_ERROR;
|
||||
case 4:
|
||||
case LOCATION_ERROR:
|
||||
return LOCATION_ERROR;
|
||||
case LOCATION_FULLTEXT_SEARCH:
|
||||
return LOCATION_FULLTEXT_SEARCH;
|
||||
case 5:
|
||||
case LOCATION_SCREEN_SEARCH:
|
||||
return LOCATION_SCREEN_SEARCH;
|
||||
}
|
||||
return LOCATION_TOKEN;
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
|
||||
enum LocationType
|
||||
{
|
||||
LOCATION_TOKEN,
|
||||
LOCATION_SCOPE,
|
||||
LOCATION_LOCAL_SYMBOL,
|
||||
LOCATION_ERROR,
|
||||
LOCATION_FULLTEXT_SEARCH,
|
||||
LOCATION_SCREEN_SEARCH
|
||||
LOCATION_TOKEN = 0,
|
||||
LOCATION_SCOPE = 1,
|
||||
LOCATION_QUALIFIER = 2,
|
||||
LOCATION_LOCAL_SYMBOL = 3,
|
||||
LOCATION_ERROR = 4,
|
||||
LOCATION_FULLTEXT_SEARCH = 5,
|
||||
LOCATION_SCREEN_SEARCH = 6
|
||||
};
|
||||
|
||||
int locationTypeToInt(LocationType type);
|
||||
|
||||
@@ -46,8 +46,12 @@ public:
|
||||
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
|
||||
const ParseLocation& location) = 0;
|
||||
|
||||
virtual void recordQualifierLocation(
|
||||
const NameHierarchy& qualifierName, const ParseLocation& location) = 0;
|
||||
|
||||
virtual void onError(const ParseLocation& location, const std::string& message, const std::string& commandline,
|
||||
bool fatal, bool indexed) = 0;
|
||||
|
||||
virtual void onLocalSymbolParsed(const std::string& name, const ParseLocation& location) = 0;
|
||||
virtual void onFileParsed(const FileInfo& fileInfo) = 0;
|
||||
virtual void onCommentParsed(const ParseLocation& location) = 0;
|
||||
|
||||
@@ -67,6 +67,12 @@ void ParserClientImpl::recordReference(
|
||||
addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN));
|
||||
}
|
||||
|
||||
void ParserClientImpl::recordQualifierLocation(const NameHierarchy& qualifierName, const ParseLocation& location)
|
||||
{
|
||||
Id nodeId = addNodeHierarchy(qualifierName, Node::NODE_NON_INDEXED);
|
||||
addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_QUALIFIER));
|
||||
}
|
||||
|
||||
void ParserClientImpl::onError(
|
||||
const ParseLocation& location, const std::string& message, const std::string& commandline,bool fatal, bool indexed)
|
||||
{
|
||||
|
||||
@@ -36,8 +36,12 @@ public:
|
||||
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
|
||||
const ParseLocation& location);
|
||||
|
||||
virtual void recordQualifierLocation(
|
||||
const NameHierarchy& qualifierName, const ParseLocation& location);
|
||||
|
||||
virtual void onError(const ParseLocation& location, const std::string& message, const std::string& commandline,
|
||||
bool fatal, bool indexed);
|
||||
|
||||
virtual void onLocalSymbolParsed(const std::string& name, const ParseLocation& location);
|
||||
virtual void onFileParsed(const FileInfo& fileInfo);
|
||||
virtual void onCommentParsed(const ParseLocation& location);
|
||||
|
||||
@@ -1264,6 +1264,12 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getSourceLocationsF
|
||||
auto it = locationIdToElementIdMap.find(sourceLocation.id);
|
||||
if (it != locationIdToElementIdMap.end())
|
||||
{
|
||||
LocationType type = intToLocationType(sourceLocation.type);
|
||||
if (type == LOCATION_QUALIFIER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FilePath path = getFileNodePath(sourceLocation.fileNodeId);
|
||||
if (path.empty())
|
||||
{
|
||||
@@ -1281,7 +1287,7 @@ std::shared_ptr<SourceLocationCollection> PersistentStorage::getSourceLocationsF
|
||||
if (!path.empty())
|
||||
{
|
||||
collection->addSourceLocation(
|
||||
intToLocationType(sourceLocation.type),
|
||||
type,
|
||||
sourceLocation.id,
|
||||
std::vector<Id>(1, it->second),
|
||||
path,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
|
||||
const size_t SqliteIndexStorage::s_storageVersion = 13;
|
||||
const size_t SqliteIndexStorage::s_storageVersion = 14;
|
||||
|
||||
SqliteIndexStorage::SqliteIndexStorage(const FilePath& dbFilePath)
|
||||
: SqliteStorage(dbFilePath.canonical())
|
||||
|
||||
@@ -40,26 +40,37 @@ void CxxAstVisitorComponentIndexer::beginTraverseNestedNameSpecifierLoc(const cl
|
||||
case clang::NestedNameSpecifier::Identifier:
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Namespace:
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(loc.getNestedNameSpecifier()->getAsNamespace()),
|
||||
SYMBOL_NAMESPACE,
|
||||
ACCESS_NONE,
|
||||
DEFINITION_NONE
|
||||
);
|
||||
{
|
||||
const NameHierarchy symbolName = getAstVisitor()->getDeclNameCache()->getValue(loc.getNestedNameSpecifier()->getAsNamespace());
|
||||
m_client->recordSymbol(
|
||||
symbolName,
|
||||
SYMBOL_NAMESPACE,
|
||||
ACCESS_NONE,
|
||||
DEFINITION_NONE
|
||||
);
|
||||
|
||||
m_client->recordQualifierLocation(
|
||||
symbolName,
|
||||
getParseLocation(loc.getLocalBeginLoc())
|
||||
);
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::NamespaceAlias:
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(loc.getNestedNameSpecifier()->getAsNamespaceAlias()),
|
||||
SYMBOL_NAMESPACE,
|
||||
ACCESS_NONE,
|
||||
DEFINITION_NONE
|
||||
);
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(loc.getNestedNameSpecifier()->getAsNamespaceAlias()->getAliasedNamespace()),
|
||||
SYMBOL_NAMESPACE,
|
||||
ACCESS_NONE,
|
||||
DEFINITION_NONE
|
||||
);
|
||||
{
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(loc.getNestedNameSpecifier()->getAsNamespaceAlias()),
|
||||
SYMBOL_NAMESPACE,
|
||||
ACCESS_NONE,
|
||||
DEFINITION_NONE
|
||||
);
|
||||
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(loc.getNestedNameSpecifier()->getAsNamespaceAlias()->getAliasedNamespace()),
|
||||
SYMBOL_NAMESPACE,
|
||||
ACCESS_NONE,
|
||||
DEFINITION_NONE
|
||||
);
|
||||
}
|
||||
break;
|
||||
case clang::NestedNameSpecifier::Global:
|
||||
case clang::NestedNameSpecifier::Super:
|
||||
@@ -84,14 +95,27 @@ void CxxAstVisitorComponentIndexer::beginTraverseNestedNameSpecifierLoc(const cl
|
||||
|
||||
if (symbolKind != SYMBOL_KIND_MAX)
|
||||
{
|
||||
const NameHierarchy symbolName = getAstVisitor()->getDeclNameCache()->getValue(recordDecl);
|
||||
m_client->recordSymbol(
|
||||
getAstVisitor()->getDeclNameCache()->getValue(recordDecl),
|
||||
symbolName,
|
||||
symbolKind,
|
||||
ACCESS_NONE,
|
||||
DEFINITION_NONE
|
||||
);
|
||||
|
||||
m_client->recordQualifierLocation(
|
||||
symbolName,
|
||||
getParseLocation(loc.getLocalBeginLoc())
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (const clang::Type* type = loc.getNestedNameSpecifier()->getAsType())
|
||||
{
|
||||
m_client->recordQualifierLocation(
|
||||
getAstVisitor()->getTypeNameCache()->getValue(type),
|
||||
getParseLocation(loc.getLocalBeginLoc())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,6 +404,8 @@ void CxxAstVisitorComponentIndexer::visitNamespaceAliasDecl(clang::NamespaceAlia
|
||||
getAstVisitor()->getDeclNameCache()->getValue(d),
|
||||
getParseLocation(d->getTargetNameLoc())
|
||||
);
|
||||
|
||||
// TODO: record other namespace as undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -688,6 +688,10 @@ void QtCodeArea::annotateText()
|
||||
const std::set<Id>& activeLocationIds = m_navigator->getCurrentActiveLocationIds();
|
||||
|
||||
std::set<Id> focusedSymbolIds = m_navigator->getActiveTokenIds();
|
||||
for (Id currentActiveId : activeSymbolIds)
|
||||
{
|
||||
focusedSymbolIds.erase(currentActiveId);
|
||||
}
|
||||
utility::append(focusedSymbolIds, m_navigator->getFocusedTokenIds());
|
||||
|
||||
bool needsUpdate = QtCodeField::annotateText(activeSymbolIds, activeLocationIds, focusedSymbolIds);
|
||||
|
||||
@@ -288,6 +288,11 @@ bool QtCodeField::annotateText(
|
||||
|
||||
annotation.isFocused = utility::shareElement(focusedSymbolIds, annotation.tokenIds);
|
||||
|
||||
if (annotation.locationType == LOCATION_QUALIFIER)
|
||||
{
|
||||
annotation.isActive = false;
|
||||
}
|
||||
|
||||
if (wasFocused != annotation.isFocused || wasActive != annotation.isActive)
|
||||
{
|
||||
m_linesToRehighlight.push_back(annotation.startLine - m_startLineNumber);
|
||||
@@ -376,7 +381,7 @@ void QtCodeField::activateAnnotations(const std::vector<const Annotation*>& anno
|
||||
bool allActive = true;
|
||||
for (const Annotation* annotation : annotations)
|
||||
{
|
||||
if (annotation->locationType == LOCATION_TOKEN)
|
||||
if (annotation->locationType == LOCATION_TOKEN || annotation->locationType == LOCATION_QUALIFIER)
|
||||
{
|
||||
if (!annotation->isActive)
|
||||
{
|
||||
@@ -614,7 +619,7 @@ std::vector<const QtCodeField::Annotation*> QtCodeField::getInteractiveAnnotatio
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
const LocationType& type = annotation.locationType;
|
||||
if ((type == LOCATION_TOKEN || type == LOCATION_LOCAL_SYMBOL || type == LOCATION_ERROR)
|
||||
if ((type == LOCATION_TOKEN || type == LOCATION_QUALIFIER || type == LOCATION_LOCAL_SYMBOL || type == LOCATION_ERROR)
|
||||
&& pos >= annotation.start && pos <= annotation.end)
|
||||
{
|
||||
annotations.push_back(&annotation);
|
||||
|
||||
@@ -55,6 +55,7 @@ JavaParser::JavaParser(std::shared_ptr<ParserClient> client, std::shared_ptr<Fil
|
||||
methods.push_back({"recordSymbolWithLocation", "(ILjava/lang/String;IIIIIII)V", (void*)&JavaParser::RecordSymbolWithLocation});
|
||||
methods.push_back({"recordSymbolWithLocationAndScope", "(ILjava/lang/String;IIIIIIIIIII)V", (void*)&JavaParser::RecordSymbolWithLocationAndScope});
|
||||
methods.push_back({"recordReference", "(IILjava/lang/String;Ljava/lang/String;IIII)V", (void*)&JavaParser::RecordReference});
|
||||
methods.push_back({"recordQualifierLocation", "(ILjava/lang/String;IIII)V", (void*)&JavaParser::RecordQualifierLocation});
|
||||
methods.push_back({"recordLocalSymbol", "(ILjava/lang/String;IIII)V", (void*)&JavaParser::RecordLocalSymbol});
|
||||
methods.push_back({"recordComment", "(IIIII)V", (void*)&JavaParser::RecordComment});
|
||||
methods.push_back({"recordError", "(ILjava/lang/String;IIIIII)V", (void*)&JavaParser::RecordError});
|
||||
@@ -222,6 +223,17 @@ void JavaParser::doRecordReference(
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordQualifierLocation(
|
||||
jstring jQualifierName,
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn
|
||||
)
|
||||
{
|
||||
m_client->recordQualifierLocation(
|
||||
NameHierarchy::deserialize(m_javaEnvironment->toStdString(jQualifierName)),
|
||||
ParseLocation(m_currentFilePath, beginLine, beginColumn, endLine, endColumn)
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordLocalSymbol(jstring jSymbolName, jint beginLine, jint beginColumn, jint endLine, jint endColumn)
|
||||
{
|
||||
m_client->onLocalSymbolParsed(
|
||||
|
||||
@@ -128,7 +128,7 @@ private:
|
||||
LOG_ERROR("parser with id " + std::to_string(parserId) + " not found"); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
DEF_RELAYING_METHOD_1(LogInfo, jstring)
|
||||
DEF_RELAYING_METHOD_1(LogWarning, jstring)
|
||||
DEF_RELAYING_METHOD_1(LogError, jstring)
|
||||
@@ -136,6 +136,7 @@ private:
|
||||
DEF_RELAYING_METHOD_8(RecordSymbolWithLocation, jstring, jint, jint, jint, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_12(RecordSymbolWithLocationAndScope, jstring, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_7(RecordReference, jint, jstring, jstring, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_5(RecordQualifierLocation, jstring, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_5(RecordLocalSymbol, jstring, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_4(RecordComment, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_7(RecordError, jstring, jint, jint, jint, jint, jint, jint)
|
||||
@@ -188,6 +189,7 @@ private:
|
||||
);
|
||||
|
||||
void doRecordReference(jint jRefType, jstring jReferencedName, jstring jContextName, jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
void doRecordQualifierLocation(jstring jQualifierName, jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
void doRecordLocalSymbol(jstring jSymbolName, jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
void doRecordComment(jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
void doRecordError(jstring jMessage, jint jFatal, jint jIndexed, jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "helper/DumpParserClient.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "utility/utility.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
@@ -146,6 +147,6 @@ private:
|
||||
|
||||
parser.buildIndex(command);
|
||||
|
||||
return TextAccess::createFromString(parserClient->m_dump);
|
||||
return TextAccess::createFromString(parserClient->m_lines);
|
||||
}
|
||||
};
|
||||
@@ -1280,6 +1280,94 @@ public:
|
||||
));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// test qualifier locations
|
||||
|
||||
void test_cxx_parser_finds_qualifier_of_access_to_global_variable_defined_in_namespace()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"namespace foo {\n"
|
||||
" namespace bar {\n"
|
||||
" int x;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"void f() {\n"
|
||||
" foo::bar::x = 9;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(client->qualifiers, "foo <7:2 7:4>"));
|
||||
TS_ASSERT(utility::containsElement<std::string>(client->qualifiers, "foo::bar <7:7 7:9>"));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_qualifier_of_access_to_static_field()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"class Foo {\n"
|
||||
"public:\n"
|
||||
" struct Bar {\n"
|
||||
" public:\n"
|
||||
" static int x;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"void f() {\n"
|
||||
" Foo::Bar::x = 9;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(client->qualifiers, "Foo <9:2 9:4>"));
|
||||
TS_ASSERT(utility::containsElement<std::string>(client->qualifiers, "Foo::Bar <9:7 9:9>"));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_qualifier_of_access_to_enum_constant()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"enum Foo {\n"
|
||||
" FOO_V\n"
|
||||
"};\n"
|
||||
"void f() {\n"
|
||||
" Foo v = Foo::FOO_V;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(client->qualifiers, "Foo <5:10 5:12>"));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_qualifier_of_reference_to_method()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"class Foo {\n"
|
||||
"public:\n"
|
||||
" static void my_int_func(int x) {\n"
|
||||
" }\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void test() {\n"
|
||||
" void(*foo)(int);\n"
|
||||
" foo = &Foo::my_int_func;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(client->qualifiers, "Foo <9:9 9:11>"));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_qualifier_of_constructor_call()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"class Foo {\n"
|
||||
"public:\n"
|
||||
" Foo(int i) {}\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"class Bar : public Foo {\n"
|
||||
"public:\n"
|
||||
" Bar() : Foo::Foo(4) {}\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(client->qualifiers, "Foo <8:10 8:12>"));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// test implicit symbols
|
||||
|
||||
|
||||
@@ -264,6 +264,6 @@ private:
|
||||
|
||||
parser.buildIndex(command);
|
||||
|
||||
return TextAccess::createFromString(parserClient->m_dump);
|
||||
return TextAccess::createFromString(parserClient->m_lines);
|
||||
}
|
||||
};
|
||||
@@ -462,6 +462,311 @@ public:
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// test finding qualifier locations
|
||||
|
||||
void test_java_parser_finds_no_qualifier_location_of_standalone_this_expression()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo;\n"
|
||||
"public class X\n"
|
||||
"{\n"
|
||||
" public void bar()\n"
|
||||
" {\n"
|
||||
" X x = this;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->qualifiers.size(), 0);
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_import_declaration()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"import foo.bar;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo <1:8 1:10>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_simple_type()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo.bar;\n"
|
||||
"public class A\n"
|
||||
"{\n"
|
||||
" public void bar(int i)\n"
|
||||
" {\n"
|
||||
" foo.bar.A a;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo <6:3 6:5>"
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.bar <6:7 6:9>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_field_access()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo;\n"
|
||||
"public class X\n"
|
||||
"{\n"
|
||||
" public int i;\n"
|
||||
" \n"
|
||||
" public void bar()\n"
|
||||
" {\n"
|
||||
" this.i = 9;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.X <8:3 8:6>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_super_field_access()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo;\n"
|
||||
"class A\n"
|
||||
"{\n"
|
||||
" int a;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"class B extends A\n"
|
||||
"{\n"
|
||||
" void foo()\n"
|
||||
" {\n"
|
||||
" B.super.a = 0;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.B <11:3 11:3>"
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.A <11:5 11:9>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_this_expression()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo;\n"
|
||||
"class A\n"
|
||||
"{\n"
|
||||
" int a;\n"
|
||||
" \n"
|
||||
" void foo()\n"
|
||||
" {\n"
|
||||
" A a = A.this;"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.A <8:9 8:9>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_method_invocation()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo;\n"
|
||||
"public class X\n"
|
||||
"{\n"
|
||||
" public static void bar()\n"
|
||||
" {\n"
|
||||
" foo.X.bar();\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo <6:3 6:5>"
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.X <6:7 6:7>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_method_invocation_on_this()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo;\n"
|
||||
"public class X\n"
|
||||
"{\n"
|
||||
" public void bar()\n"
|
||||
" {\n"
|
||||
" this.bar();\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.X <6:3 6:6>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_super_method_invocation()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"package foo;\n"
|
||||
"public class X\n"
|
||||
"{\n"
|
||||
" public class A\n"
|
||||
" {\n"
|
||||
" void bar()\n"
|
||||
" {\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" public class B extends A\n"
|
||||
" {\n"
|
||||
" void bar()\n"
|
||||
" {\n"
|
||||
" foo.X.B.super.bar();\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo <15:4 15:6>"
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.X <15:8 15:8>"
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.X.B <15:10 15:10>"
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "foo.X.A <15:12 15:16>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_creation_reference()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"public class A\n"
|
||||
"{\n"
|
||||
" public interface Functor\n"
|
||||
" {\n"
|
||||
" public void doSomething();\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" public class Bar\n"
|
||||
" {\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" void foo()\n"
|
||||
" {\n"
|
||||
" Functor method = A.Bar::new;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "A <14:20 14:20>"
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "A.Bar <14:22 14:24>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_expression_method_reference()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"public class A\n"
|
||||
"{\n"
|
||||
" public interface Functor\n"
|
||||
" {\n"
|
||||
" public void doSomething();\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" public class B\n"
|
||||
" {\n"
|
||||
" void bar()\n"
|
||||
" {\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" void foo()\n"
|
||||
" {\n"
|
||||
" Functor method = B::bar;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "A.B <17:20 17:20>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_super_method_reference()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"public class A {\n"
|
||||
" public interface Functor {\n"
|
||||
" public void doSomething();\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" public class B {\n"
|
||||
" void bar() {\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" public class C extends B {\n"
|
||||
" void foo() {\n"
|
||||
" Functor method = super::bar;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "A.B <13:21 13:25>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_java_parser_finds_qualifier_location_of_class_instance_creation()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"public class A {\n"
|
||||
" public interface Functor {\n"
|
||||
" public void doSomething();\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" public class B {\n"
|
||||
" void bar() {\n"
|
||||
" B b = new A.B();"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->qualifiers, "A <8:14 8:14>"
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// test finding usages of symbols
|
||||
|
||||
@@ -578,7 +883,7 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->typeUses, "void A.bar() -> A.B <8:3 8:5>"
|
||||
client->typeUses, "void A.bar() -> A.B <8:5 8:5>"
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -10,39 +10,39 @@ class DumpParserClient : public ParserClient
|
||||
{
|
||||
public:
|
||||
DumpParserClient()
|
||||
: m_dump("")
|
||||
: m_lines("")
|
||||
{
|
||||
}
|
||||
|
||||
virtual Id recordSymbol(
|
||||
const NameHierarchy& symbolName, SymbolKind symbolKind,
|
||||
AccessKind access, DefinitionKind definitionKind)
|
||||
AccessKind access, DefinitionKind definitionKind) override
|
||||
{
|
||||
m_dump += symbolKindToString(symbolKind) + " " + addAccessPrefix(symbolName.getQualifiedNameWithSignature(), access) + "\n";
|
||||
recordLine(symbolKindToString(symbolKind) + " " + addAccessPrefix(symbolName.getQualifiedNameWithSignature(), access) + "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual Id recordSymbol(
|
||||
const NameHierarchy& symbolName, SymbolKind symbolKind,
|
||||
const ParseLocation& location,
|
||||
AccessKind access, DefinitionKind definitionKind)
|
||||
AccessKind access, DefinitionKind definitionKind) override
|
||||
{
|
||||
m_dump += symbolKindToString(symbolKind) + " " + addLocationSuffix(addAccessPrefix(symbolName.getQualifiedNameWithSignature(), access) + " [" + location.filePath.fileName(), location) + "]\n";
|
||||
recordLine(symbolKindToString(symbolKind) + " " + addLocationSuffix(addAccessPrefix(symbolName.getQualifiedNameWithSignature(), access) + " [" + location.filePath.fileName(), location) + "]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual Id recordSymbol(
|
||||
const NameHierarchy& symbolName, SymbolKind symbolKind,
|
||||
const ParseLocation& location, const ParseLocation& scopeLocation,
|
||||
AccessKind access, DefinitionKind definitionKind)
|
||||
AccessKind access, DefinitionKind definitionKind) override
|
||||
{
|
||||
m_dump += symbolKindToString(symbolKind) + " " + addLocationSuffix(addAccessPrefix(symbolName.getQualifiedNameWithSignature(), access) + " [" + location.filePath.fileName(), location, scopeLocation) + "]\n";
|
||||
recordLine(symbolKindToString(symbolKind) + " " + addLocationSuffix(addAccessPrefix(symbolName.getQualifiedNameWithSignature(), access) + " [" + location.filePath.fileName(), location, scopeLocation) + "]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void recordReference(
|
||||
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
|
||||
const ParseLocation& location)
|
||||
const ParseLocation& location) override
|
||||
{
|
||||
std::string contextNameString = contextName.getQualifiedNameWithSignature();
|
||||
try
|
||||
@@ -56,33 +56,47 @@ public:
|
||||
{
|
||||
// do nothing and use the old contectNameString
|
||||
}
|
||||
m_dump += referenceKindToString(referenceKind) + " " + addLocationSuffix(contextNameString + " -> " + referencedName.getQualifiedNameWithSignature() + " [" + location.filePath.fileName(), location) + "]\n";
|
||||
recordLine(referenceKindToString(referenceKind) + " " + addLocationSuffix(contextNameString + " -> " + referencedName.getQualifiedNameWithSignature() + " [" + location.filePath.fileName(), location) + "]\n");
|
||||
}
|
||||
|
||||
void recordQualifierLocation(const NameHierarchy& qualifierName, const ParseLocation& location) override
|
||||
{
|
||||
recordLine("QUALIFIER: " + addLocationSuffix(qualifierName.getQualifiedNameWithSignature() + " [" + location.filePath.fileName(), location) + "]\n");
|
||||
}
|
||||
|
||||
virtual void onError(const ParseLocation& location, const std::string& message, const std::string& commandline,
|
||||
bool fatal, bool indexed)
|
||||
bool fatal, bool indexed) override
|
||||
{
|
||||
m_dump += "ERROR: " + addLocationSuffix(message + " [" + location.filePath.fileName(), location) + "]\n";
|
||||
recordLine("ERROR: " + addLocationSuffix(message + " [" + location.filePath.fileName(), location) + "]\n");
|
||||
}
|
||||
|
||||
virtual void onLocalSymbolParsed(const std::string& name, const ParseLocation& location)
|
||||
virtual void onLocalSymbolParsed(const std::string& name, const ParseLocation& location) override
|
||||
{
|
||||
m_dump += "LOCAL_SYMBOL: " + addLocationSuffix(name + " [" + location.filePath.fileName(), location) + "]\n";
|
||||
recordLine("LOCAL_SYMBOL: " + addLocationSuffix(name + " [" + location.filePath.fileName(), location) + "]\n");
|
||||
}
|
||||
|
||||
virtual void onFileParsed(const FileInfo& fileInfo)
|
||||
virtual void onFileParsed(const FileInfo& fileInfo) override
|
||||
{
|
||||
m_dump += "FILE: " + fileInfo.path.fileName() + "\n";
|
||||
recordLine("FILE: " + fileInfo.path.fileName() + "\n");
|
||||
}
|
||||
|
||||
virtual void onCommentParsed(const ParseLocation& location)
|
||||
virtual void onCommentParsed(const ParseLocation& location) override
|
||||
{
|
||||
m_dump += "COMMENT: " + addLocationSuffix("comment [" + location.filePath.fileName(), location) + "]\n";
|
||||
recordLine("COMMENT: " + addLocationSuffix("comment [" + location.filePath.fileName(), location) + "]\n");
|
||||
}
|
||||
|
||||
std::string m_dump;
|
||||
std::string m_lines;
|
||||
|
||||
private:
|
||||
void recordLine(const std::string& message)
|
||||
{
|
||||
if (m_recordedLines.find(message) == m_recordedLines.end())
|
||||
{
|
||||
m_recordedLines.insert(message);
|
||||
m_lines += message;
|
||||
}
|
||||
}
|
||||
|
||||
std::string symbolKindToString(SymbolKind symbolKind) const
|
||||
{
|
||||
switch (symbolKind)
|
||||
@@ -162,6 +176,8 @@ private:
|
||||
}
|
||||
return "REFERENCE_UNDEFINED";
|
||||
}
|
||||
|
||||
std::set<std::string> m_recordedLines;
|
||||
};
|
||||
|
||||
#endif // DUMP_PARSER_CLIENT_H
|
||||
|
||||
@@ -102,6 +102,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void recordQualifierLocation(
|
||||
const NameHierarchy& qualifierName, const ParseLocation& location)
|
||||
{
|
||||
qualifiers.push_back(addLocationSuffix(qualifierName.getQualifiedNameWithSignature(), location));
|
||||
}
|
||||
|
||||
virtual void onError(const ParseLocation& location, const std::string& message, const std::string& commandline,
|
||||
bool fatal, bool indexed)
|
||||
{
|
||||
@@ -124,6 +130,7 @@ public:
|
||||
}
|
||||
|
||||
std::vector<std::string> errors;
|
||||
std::vector<std::string> qualifiers;
|
||||
|
||||
std::vector<std::string> packages;
|
||||
std::vector<std::string> typedefs;
|
||||
|
||||
Reference in New Issue
Block a user