Skip to content

Commit

Permalink
[v0.0.3] Added tests, added support of RG3_OverrideLocation annotatio…
Browse files Browse the repository at this point in the history
…n. Added support of 'angled locations' (and test on python side).
  • Loading branch information
DronCode committed Mar 20, 2024
1 parent 327cfc2 commit a939a80
Show file tree
Hide file tree
Showing 11 changed files with 382 additions and 23 deletions.
8 changes: 8 additions & 0 deletions Cpp/include/RG3/Cpp/BuiltinTags.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,13 @@ namespace rg3::cpp
* @note Use string escape symbol \" to use strings inside tags inside annotation
*/
static constexpr std::string_view kRegisterTag { "RG3_RegisterTag" };

/**
* @brief Annotation for override final type location place. Semantics: RG3_OverrideLication[new/path]
* @note Path will be marked as 'angled' ie to use as #include <my_path>
* @note Line & column will be always zeroed
* @note Only last annotation will affect final path!
*/
static constexpr std::string_view kOverrideLocation { "RG3_OverrideLocation" };
};
}
4 changes: 3 additions & 1 deletion Cpp/include/RG3/Cpp/DefinitionLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ namespace rg3::cpp
{
public:
DefinitionLocation();
DefinitionLocation(const std::filesystem::path& location, int line, int offset);
DefinitionLocation(const std::filesystem::path& location, int line, int offset, bool bAngled = false);

[[nodiscard]] const std::filesystem::path& getFsLocation() const;
[[nodiscard]] std::string getPath() const;
[[nodiscard]] int getLine() const;
[[nodiscard]] int getInLineOffset() const;
[[nodiscard]] bool isAngledPath() const;

bool operator==(const DefinitionLocation& other) const;
bool operator!=(const DefinitionLocation& other) const;
Expand All @@ -24,5 +25,6 @@ namespace rg3::cpp
std::filesystem::path m_fsLocation {};
int m_line { 0 };
int m_offset { 0 };
bool m_bAngled { false };
};
}
1 change: 1 addition & 0 deletions Cpp/include/RG3/Cpp/TypeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace rg3::cpp
[[nodiscard]] const CppNamespace& getNamespace() const;
[[nodiscard]] const std::string& getPrettyName() const;
[[nodiscard]] const DefinitionLocation& getDefinition() const;
void setDefinition(DefinitionLocation&& newLoc);

[[nodiscard]] bool areSame(const TypeBase* pOther) const;

Expand Down
10 changes: 8 additions & 2 deletions Cpp/source/DefinitionLocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
namespace rg3::cpp
{
DefinitionLocation::DefinitionLocation() = default;
DefinitionLocation::DefinitionLocation(const std::filesystem::path& location, int line, int offset)
DefinitionLocation::DefinitionLocation(const std::filesystem::path& location, int line, int offset, bool bAngled)
: m_fsLocation(location)
, m_line(line)
, m_offset(offset)
, m_bAngled(bAngled)
{
}

Expand All @@ -31,9 +32,14 @@ namespace rg3::cpp
return m_offset;
}

bool DefinitionLocation::isAngledPath() const
{
return m_bAngled;
}

bool DefinitionLocation::operator==(const DefinitionLocation& other) const
{
return m_fsLocation == other.m_fsLocation && m_line == other.m_line && m_offset == other.m_offset;
return m_fsLocation == other.m_fsLocation && m_line == other.m_line && m_offset == other.m_offset && m_bAngled == other.m_bAngled;
}

bool DefinitionLocation::operator!=(const DefinitionLocation& other) const
Expand Down
8 changes: 8 additions & 0 deletions Cpp/source/Tag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ namespace rg3::cpp
while (!argumentString.empty() && argumentString[0] == ' ')
argumentString.erase(0, 1);

// Remove escape symbols
auto it = argumentString.find('\"');
while (it != std::string::npos)
{
argumentString.erase(it, 1);
it = argumentString.find('\"');
}

if (argumentString.empty())
continue;

Expand Down
5 changes: 5 additions & 0 deletions Cpp/source/TypeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ namespace rg3::cpp
return m_location;
}

void TypeBase::setDefinition(rg3::cpp::DefinitionLocation&& newLoc)
{
m_location = std::move(newLoc);
}

bool TypeBase::areSame(const TypeBase* pOther) const
{
if (!pOther)
Expand Down
22 changes: 22 additions & 0 deletions LLVM/source/Visitors/CxxClassTypeVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <clang/AST/Decl.h>

#include <boost/algorithm/string.hpp>
#include <optional>


namespace rg3::llvm::visitors
Expand Down Expand Up @@ -332,6 +333,7 @@ namespace rg3::llvm::visitors
// Try to locate properties
std::vector<std::string> vFunctionsToCollect {};
std::vector<PropertyDescription> vExtraProperties {};
std::optional<std::string> kOverrideLocationPath = std::nullopt;
rg3::cpp::Tags sExtraTags;

for (const auto* pAttr : cxxRecordDecl->attrs())
Expand Down Expand Up @@ -395,6 +397,17 @@ namespace rg3::llvm::visitors
}
}
}
else if (annotation.starts_with(rg3::cpp::BuiltinAnnotations::kOverrideLocation))
{
// Here we have annotation to override type location
std::vector<std::string> splitResult;
boost::algorithm::split(splitResult, annotation, boost::is_any_of("[]"));

if (splitResult.size() >= 2)
{
kOverrideLocationPath = splitResult[1];
}
}
}
}

Expand Down Expand Up @@ -551,6 +564,12 @@ namespace rg3::llvm::visitors
// Override in any case
vFoundExtraTypes[i]->getTags().getTags()[name] = tag;
}

// Override location if allowed
if (kOverrideLocationPath.has_value())
{
vFoundExtraTypes[i]->setDefinition(rg3::cpp::DefinitionLocation(kOverrideLocationPath.value(), 0, 0, true));
}
}
}
}
Expand Down Expand Up @@ -645,6 +664,9 @@ namespace rg3::llvm::visitors

CxxClassTypeVisitor sClassVisitor { newConfig };


// NOTE: Here we should handle template, template specializations and something like that. For v0.0.3 I'm ignoring that case, so nothing will be found.

if (auto* asCxxRecord = ::llvm::dyn_cast<clang::CXXRecordDecl>(pAsRecord->getDecl()))
{
sClassVisitor.VisitCXXRecordDecl(asCxxRecord);
Expand Down
3 changes: 3 additions & 0 deletions PyBind/rg3py.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ class Location:
@property
def column(self) -> int: ...

@property
def angled(self) -> bool: ...


class CppNamespace:
def __eq__(self, other) -> bool: ...
Expand Down
1 change: 1 addition & 0 deletions PyBind/source/PyBind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ BOOST_PYTHON_MODULE(rg3py)
.add_property("path", make_function(&rg3::cpp::DefinitionLocation::getPath, return_value_policy<return_by_value>()))
.add_property("line", &rg3::cpp::DefinitionLocation::getLine)
.add_property("column", &rg3::cpp::DefinitionLocation::getInLineOffset)
.add_property("angled", &rg3::cpp::DefinitionLocation::isAngledPath)
;

class_<rg3::cpp::TagArgument>("TagArgument")
Expand Down
58 changes: 58 additions & 0 deletions Tests/PyIntegration/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,3 +593,61 @@ def test_check_global_type_aliases():
assert as_alias2.target_description.is_const_ptr is False
assert as_alias2.target_description.is_template is False
assert as_alias2.target_description.is_const is False


def test_check_type_annotations():
analyzer: rg3py.CodeAnalyzer = rg3py.CodeAnalyzer.make()

analyzer.set_code("""
#include <string>
// Registrator
template <typename T> struct RegisterType {};
template <> struct
__attribute__((annotate("RG3_RegisterRuntime")))
__attribute__((annotate("RG3_OverrideLocation[string]")))
RegisterType<std::string> {
using Type = std::string;
};
/// @runtime
struct Geo
{
/// @property(Lat)
double rLat;
/// @property(Long)
double rLong;
};
""")

analyzer.set_cpp_standard(rg3py.CppStandard.CXX_17)
analyzer.analyze()

assert len(analyzer.issues) == 0
assert len(analyzer.types) == 2

assert analyzer.types[0].name == "string"
assert analyzer.types[0].pretty_name == "std::string"
assert analyzer.types[0].kind == rg3py.CppTypeKind.TK_STRUCT_OR_CLASS
assert analyzer.types[0].location.path == "string"
assert analyzer.types[0].location.line == 0
assert analyzer.types[0].location.column == 0
assert analyzer.types[0].location.angled
assert len(analyzer.types[0].properties) == 0
assert len(analyzer.types[0].functions) == 0

assert analyzer.types[1].name == "Geo"
assert analyzer.types[1].pretty_name == "Geo"
assert analyzer.types[1].kind == rg3py.CppTypeKind.TK_STRUCT_OR_CLASS
assert analyzer.types[1].location.path == "id0.hpp"
assert analyzer.types[1].location.line > 0
assert analyzer.types[1].location.column > 0
assert analyzer.types[1].location.angled == False
assert len(analyzer.types[1].properties) == 2
assert analyzer.types[1].properties[0].name == "rLat"
assert analyzer.types[1].properties[0].alias == "Lat"
assert analyzer.types[1].properties[1].name == "rLong"
assert analyzer.types[1].properties[1].alias == "Long"
assert len(analyzer.types[1].functions) == 0
Loading

0 comments on commit a939a80

Please sign in to comment.