logic: name qualifiers of symbols are clickable now

This commit is contained in:
mlangkabel
2017-10-11 11:08:01 +02:00
parent 896fbf09b6
commit cf984ca245
216 changed files with 11261 additions and 15182 deletions
+2 -1
View File
@@ -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);
}
};
+88
View File
@@ -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
+1 -1
View File
@@ -264,6 +264,6 @@ private:
parser.buildIndex(command);
return TextAccess::createFromString(parserClient->m_dump);
return TextAccess::createFromString(parserClient->m_lines);
}
};
+306 -1
View File
@@ -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>"
));
}
+34 -18
View File
@@ -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
+7
View File
@@ -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;