diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2013-12-10 12:57:38 +0000 |
---|---|---|
committer | Philip Withnall <philip.withnall@collabora.co.uk> | 2013-12-10 12:57:38 +0000 |
commit | 20b5d8dafea938955dfbc22c68cce61726df3cc1 (patch) | |
tree | 8023da0d028d6760de68b7b2ff22ab1bf3b1a43a /clang-plugin | |
parent | 8f8d2944fae776d08681e036fa0de55e28708089 (diff) |
clang-plugin: Factor out GIR repository management
It will be used by several different plugins, so needs to be factored
out into a shared object.
Diffstat (limited to 'clang-plugin')
-rw-r--r-- | clang-plugin/gir-attributes.cpp | 81 | ||||
-rw-r--r-- | clang-plugin/gir-attributes.h | 23 | ||||
-rw-r--r-- | clang-plugin/gir-manager.cpp | 108 | ||||
-rw-r--r-- | clang-plugin/gir-manager.h | 52 | ||||
-rw-r--r-- | clang-plugin/plugin.cpp | 8 |
5 files changed, 174 insertions, 98 deletions
diff --git a/clang-plugin/gir-attributes.cpp b/clang-plugin/gir-attributes.cpp index de97306..3f590f2 100644 --- a/clang-plugin/gir-attributes.cpp +++ b/clang-plugin/gir-attributes.cpp @@ -28,47 +28,6 @@ #include "debug.h" #include "gir-attributes.h" -GirAttributesConsumer::GirAttributesConsumer () -{ - this->_repo = g_irepository_get_default (); -} - -GirAttributesConsumer::~GirAttributesConsumer () -{ - /* Nothing to see here. */ -} - -void -GirAttributesConsumer::load_namespace (std::string& gi_namespace, - std::string& gi_version, GError **error) -{ - /* Load the GIR typelib. */ - GITypelib* typelib = g_irepository_require (this->_repo, - gi_namespace.c_str (), - gi_version.c_str (), - (GIRepositoryLoadFlags) 0, - error); - - if (typelib == NULL) - return; - - /* Get the C prefix from the repository and convert it to lower case. */ - const char *c_prefix = - g_irepository_get_c_prefix (this->_repo, - gi_namespace.c_str ()); - - Nspace r = Nspace (); - r.nspace = gi_namespace; - r.version = gi_version; - r.c_prefix = std::string (c_prefix); - r.typelib = typelib; - - std::transform (r.c_prefix.begin (), r.c_prefix.end (), - r.c_prefix.begin (), ::tolower); - - this->_typelibs.push_back (r); -} - /* Determine whether a type should be const, given its (transfer) annotation and * base type. */ static bool @@ -143,41 +102,8 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) return; /* Try to find typelib information about the function. */ - GIBaseInfo *info = NULL; - std::string func_name = func.getNameAsString (); /* TODO: expensive? */ - std::string func_name_stripped; - - for (std::vector<Nspace>::const_iterator it = this->_typelibs.begin (); - it != this->_typelibs.end (); ++it) { - Nspace r = *it; - - DEBUG ("Looking for function " << func_name << - " in repository " << r.nspace << " (version " << - r.version << ", C prefix ‘" << r.c_prefix << "’)."); - - /* The func_name includes the namespace, which needs stripping. - * e.g. g_irepository_find_by_name → find_by_name. */ - if (func_name.compare (0, r.c_prefix.size (), - r.c_prefix) == 0) { - size_t prefix_len = - r.c_prefix.size () + 1 /* underscore */; - func_name_stripped = func_name.substr (prefix_len); - } else { - DEBUG ("\tDoesn’t match C prefix ‘" << r.c_prefix << - "’."); - continue; - } - - info = g_irepository_find_by_name (this->_repo, - r.nspace.c_str (), - func_name_stripped.c_str ()); - - if (info != NULL) { - /* Successfully found an entry in the typelib. */ - DEBUG ("Found info!"); - break; - } - } + const std::string func_name = func.getNameAsString (); /* TODO: expensive? */ + GIBaseInfo *info = this->_gir_manager.find_function_info (func_name); if (info == NULL) return; @@ -309,8 +235,7 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) llvm::errs () << "Error: Unhandled GI type " << g_base_info_get_type (info) << " in introspection info for function ‘" << - func_name << "’ (" << func_name_stripped << - ").\n"; + func_name << "’.\n"; } g_base_info_unref (info); diff --git a/clang-plugin/gir-attributes.h b/clang-plugin/gir-attributes.h index e12165e..2b242e6 100644 --- a/clang-plugin/gir-attributes.h +++ b/clang-plugin/gir-attributes.h @@ -28,30 +28,19 @@ #include <girepository.h> +#include "gir-manager.h" + using namespace clang; class GirAttributesConsumer : public ASTConsumer { -private: - struct Nspace { - /* All non-NULL. */ - std::string nspace; - std::string version; - std::string c_prefix; - - GITypelib* typelib; /* unowned */ - }; - - GIRepository* _repo; /* unowned */ - std::vector<Nspace> _typelibs; public: - GirAttributesConsumer (); - ~GirAttributesConsumer (); - - void load_namespace (std::string& gi_namespace, std::string& gi_version, - GError **error); + explicit GirAttributesConsumer (const GirManager& gir_manager) : + _gir_manager (gir_manager) {} private: + const GirManager& _gir_manager; + void _handle_function_decl (FunctionDecl& func); public: virtual bool HandleTopLevelDecl (DeclGroupRef decl_group); diff --git a/clang-plugin/gir-manager.cpp b/clang-plugin/gir-manager.cpp new file mode 100644 index 0000000..f75f564 --- /dev/null +++ b/clang-plugin/gir-manager.cpp @@ -0,0 +1,108 @@ +/* -*- Mode: C++; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * gnome-clang + * Copyright © 2013 Collabora Ltd. + * + * gnome-clang is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gnome-clang is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gnome-clang. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Philip Withnall <philip.withnall@collabora.co.uk> + */ + +#include <girepository.h> +#include <gitypes.h> + +#include <clang/AST/Attr.h> + +#include "debug.h" +#include "gir-manager.h" + +GirManager::GirManager () +{ + this->_repo = g_irepository_get_default (); +} + +void +GirManager::load_namespace (const std::string& gi_namespace, + const std::string& gi_version, + GError** error) +{ + /* Load the GIR typelib. */ + GITypelib* typelib = g_irepository_require (this->_repo, + gi_namespace.c_str (), + gi_version.c_str (), + (GIRepositoryLoadFlags) 0, + error); + + if (typelib == NULL) + return; + + /* Get the C prefix from the repository and convert it to lower case. */ + const char *c_prefix = + g_irepository_get_c_prefix (this->_repo, + gi_namespace.c_str ()); + + Nspace r = Nspace (); + r.nspace = gi_namespace; + r.version = gi_version; + r.c_prefix = std::string (c_prefix); + r.typelib = typelib; + + std::transform (r.c_prefix.begin (), r.c_prefix.end (), + r.c_prefix.begin (), ::tolower); + + this->_typelibs.push_back (r); +} + +/* Try to find typelib information about the function. */ +GIBaseInfo* +GirManager::find_function_info (const std::string& func_name) const +{ + GIBaseInfo *info = NULL; + std::string func_name_stripped; + + for (std::vector<Nspace>::const_iterator it = this->_typelibs.begin (); + it != this->_typelibs.end (); ++it) { + Nspace r = *it; + + DEBUG ("Looking for function " << func_name << + " in repository " << r.nspace << " (version " << + r.version << ", C prefix ‘" << r.c_prefix << "’)."); + + /* The func_name includes the namespace, which needs stripping. + * e.g. g_irepository_find_by_name → find_by_name. */ + if (func_name.compare (0, r.c_prefix.size (), + r.c_prefix) == 0) { + size_t prefix_len = + r.c_prefix.size () + 1 /* underscore */; + func_name_stripped = func_name.substr (prefix_len); + } else { + DEBUG ("\tDoesn’t match C prefix ‘" << r.c_prefix << + "’."); + continue; + } + + info = g_irepository_find_by_name (this->_repo, + r.nspace.c_str (), + func_name_stripped.c_str ()); + + if (info != NULL) { + /* Successfully found an entry in the typelib. */ + DEBUG ("Found info!"); + break; + } + } + + return info; +} diff --git a/clang-plugin/gir-manager.h b/clang-plugin/gir-manager.h new file mode 100644 index 0000000..c78afae --- /dev/null +++ b/clang-plugin/gir-manager.h @@ -0,0 +1,52 @@ +/* -*- Mode: C++; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * gnome-clang + * Copyright © 2013 Collabora Ltd. + * + * gnome-clang is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gnome-clang is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gnome-clang. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Philip Withnall <philip.withnall@collabora.co.uk> + */ + +#ifndef GNOME_CLANG_GIR_MANAGER_H +#define GNOME_CLANG_GIR_MANAGER_H + +#include <girepository.h> + +class GirManager { +private: + struct Nspace { + /* All non-NULL. */ + std::string nspace; + std::string version; + std::string c_prefix; + + GITypelib* typelib; /* unowned */ + }; + + GIRepository* _repo; /* unowned */ + std::vector<Nspace> _typelibs; + +public: + GirManager (); + + void load_namespace (const std::string& gi_namespace, + const std::string& gi_version, + GError** error); + + GIBaseInfo* find_function_info (const std::string& func_name) const; +}; + +#endif /* !GNOME_CLANG_GIR_MANAGER_H */ diff --git a/clang-plugin/plugin.cpp b/clang-plugin/plugin.cpp index d728f5b..cbf5977 100644 --- a/clang-plugin/plugin.cpp +++ b/clang-plugin/plugin.cpp @@ -42,12 +42,14 @@ private: std::unique_ptr<GirAttributesConsumer> _gir_consumer; std::unique_ptr<GAssertAttributesConsumer> _gassert_consumer; + GirManager _gir_manager; + public: GnomeAction () { this->_gir_consumer = std::unique_ptr<GirAttributesConsumer> ( - new GirAttributesConsumer ()); + new GirAttributesConsumer (this->_gir_manager)); this->_gassert_consumer = std::unique_ptr<GAssertAttributesConsumer> ( new GAssertAttributesConsumer ()); @@ -111,8 +113,8 @@ private: /* Load the repository. */ GError *error = NULL; - this->_gir_consumer->load_namespace (gi_namespace, gi_version, - &error); + this->_gir_manager.load_namespace (gi_namespace, gi_version, + &error); if (error != NULL) { DiagnosticsEngine &d = CI.getDiagnostics (); unsigned int id = d.getCustomDiagID ( |