Added dependency checking to return values in wrap, as well as forward declarations

release/4.3a0
Alex Cunningham 2011-12-15 21:23:20 +00:00
parent a64c9bbb83
commit 56bce0ca9f
6 changed files with 54 additions and 22 deletions

View File

@ -45,8 +45,10 @@
/** /**
* Status: * Status:
* - TODO: global functions * - TODO: global functions
* - TODO: type dependencies only apply to arguments
* - TODO: default values for arguments * - TODO: default values for arguments
* - TODO: overloaded functions * - TODO: overloaded functions
* - TODO: signatures for constructors can be ambiguous if two types have the same first letter
* - TODO: Handle Rot3M conversions to quaternions * - TODO: Handle Rot3M conversions to quaternions
*/ */
@ -195,7 +197,7 @@ class SharedDiagonal {
#include <gtsam/linear/SharedGaussian.h> #include <gtsam/linear/SharedGaussian.h>
class SharedNoiseModel { class SharedNoiseModel {
// FIXME: this generates only one constructor // FIXME: this generates only one constructor because "SharedDiagonal" and "SharedGaussian" both start with 'S'
SharedNoiseModel(const SharedDiagonal& model); SharedNoiseModel(const SharedDiagonal& model);
SharedNoiseModel(const SharedGaussian& model); SharedNoiseModel(const SharedGaussian& model);
}; };

View File

@ -56,6 +56,7 @@ Module::Module(const string& interfacePath,
namespace_includes, /// current set of includes namespace_includes, /// current set of includes
namespaces_return; /// namespace for current return type namespaces_return; /// namespace for current return type
string include_path = ""; string include_path = "";
string class_name = "";
const string null_str = ""; const string null_str = "";
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -79,7 +80,7 @@ Module::Module(const string& interfacePath,
Rule eigenType_p = Rule eigenType_p =
(str_p("Vector") | "Matrix"); (str_p("Vector") | "Matrix");
Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p; Rule className_p = (lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p)[assign_a(class_name)];
Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p; Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p;
@ -199,10 +200,14 @@ Module::Module(const string& interfacePath,
[pop_a(namespaces)] [pop_a(namespaces)]
[pop_a(namespace_includes)]; [pop_a(namespace_includes)];
Rule using_namespace_p = str_p("using") >> str_p("namespace") Rule using_namespace_p =
str_p("using") >> str_p("namespace")
>> namespace_name_p[push_back_a(using_namespaces)] >> ch_p(';'); >> namespace_name_p[push_back_a(using_namespaces)] >> ch_p(';');
Rule module_content_p = comments_p | using_namespace_p | class_p | namespace_def_p ; Rule forward_delcaration_p =
(str_p("class") >> className_p >> ch_p(';'))[push_back_a(forward_declarations, class_name)];
Rule module_content_p = comments_p | using_namespace_p | forward_delcaration_p | class_p | namespace_def_p ;
Rule module_p = *module_content_p >> !end_p; Rule module_p = *module_content_p >> !end_p;
@ -255,6 +260,18 @@ void verifyArguments(const vector<string>& validArgs, const vector<T>& vt) {
} }
} }
/* ************************************************************************* */
template<class T>
void verifyReturnTypes(const vector<string>& validtypes, const vector<T>& vt) {
BOOST_FOREACH(const T& t, vt) {
const ReturnValue& retval = t.returnVal;
if (find(validtypes.begin(), validtypes.end(), retval.qualifiedType1("::")) == validtypes.end())
throw DependencyMissing(retval.qualifiedType1("::"), t.name);
if (retval.isPair && find(validtypes.begin(), validtypes.end(), retval.qualifiedType2("::")) == validtypes.end())
throw DependencyMissing(retval.qualifiedType2("::"), t.name);
}
}
/* ************************************************************************* */ /* ************************************************************************* */
void Module::matlab_code(const string& toolboxPath, void Module::matlab_code(const string& toolboxPath,
const string& mexExt, const string& mexFlags) const { const string& mexExt, const string& mexFlags) const {
@ -286,22 +303,23 @@ void Module::matlab_code(const string& toolboxPath,
make_ofs << "MEXENDING = " << mexExt << "\n"; make_ofs << "MEXENDING = " << mexExt << "\n";
make_ofs << "mex_flags = " << mexFlags << "\n\n"; make_ofs << "mex_flags = " << mexFlags << "\n\n";
//Dependency check list // Dependency check list
vector<string> validArgs; vector<string> validTypes = forward_declarations;
validArgs.push_back("string"); validTypes.push_back("void");
validArgs.push_back("int"); validTypes.push_back("string");
validArgs.push_back("bool"); validTypes.push_back("int");
validArgs.push_back("size_t"); validTypes.push_back("bool");
validArgs.push_back("double"); validTypes.push_back("size_t");
validArgs.push_back("Vector"); validTypes.push_back("double");
validArgs.push_back("Matrix"); validTypes.push_back("Vector");
validTypes.push_back("Matrix");
// add 'all' to Makefile // add 'all' to Makefile
make_ofs << "all: "; make_ofs << "all: ";
BOOST_FOREACH(Class cls, classes) { BOOST_FOREACH(Class cls, classes) {
make_ofs << cls.qualifiedName() << " "; make_ofs << cls.qualifiedName() << " ";
//Create a list of parsed classes for dependency checking //Create a list of parsed classes for dependency checking
validArgs.push_back(cls.qualifiedName("::")); validTypes.push_back(cls.qualifiedName("::"));
} }
make_ofs << "\n\n"; make_ofs << "\n\n";
@ -317,9 +335,13 @@ void Module::matlab_code(const string& toolboxPath,
cls.matlab_proxy(classFile); cls.matlab_proxy(classFile);
// verify all of the function arguments // verify all of the function arguments
verifyArguments<Constructor>(validArgs, cls.constructors); verifyArguments<Constructor>(validTypes, cls.constructors);
verifyArguments<StaticMethod>(validArgs, cls.static_methods); verifyArguments<StaticMethod>(validTypes, cls.static_methods);
verifyArguments<Method>(validArgs, cls.methods); verifyArguments<Method>(validTypes, cls.methods);
// verify function return types
verifyReturnTypes<StaticMethod>(validTypes, cls.static_methods);
verifyReturnTypes<Method>(validTypes, cls.methods);
// create constructor and method wrappers // create constructor and method wrappers
cls.matlab_constructors(toolboxPath,using_namespaces); cls.matlab_constructors(toolboxPath,using_namespaces);

View File

@ -32,6 +32,7 @@ struct Module {
std::vector<Class> classes; ///< list of classes std::vector<Class> classes; ///< list of classes
bool verbose; ///< verbose flag bool verbose; ///< verbose flag
std::vector<std::string> using_namespaces; ///< all default namespaces std::vector<std::string> using_namespaces; ///< all default namespaces
std::vector<std::string> forward_declarations;
/// constructor that parses interface file /// constructor that parses interface file
Module(const std::string& interfacePath, Module(const std::string& interfacePath,

View File

@ -4,6 +4,8 @@
// location of namespace isn't significant // location of namespace isn't significant
using namespace geometry; using namespace geometry;
class VectorNotEigen;
class Point2 { class Point2 {
Point2(); Point2();
Point2(double x, double y); Point2(double x, double y);

View File

@ -13,6 +13,7 @@ class Pose3 {
double x() const; double x() const;
double y() const; double y() const;
double z() const; double z() const;
Rot3 testReturnType() const; // Throw here
Matrix matrix() const; Matrix matrix() const;
Matrix adjointMap() const; Matrix adjointMap() const;
Pose3 compose(const Pose3& p2); Pose3 compose(const Pose3& p2);

View File

@ -57,12 +57,12 @@ TEST( wrap, check_exception ) {
CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",enable_verbose), CantOpenFile); CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",enable_verbose), CantOpenFile);
// clean out previous generated code // clean out previous generated code
string cleanCmd = "rm -rf actual"; string cleanCmd = "rm -rf actual_deps";
system(cleanCmd.c_str()); system(cleanCmd.c_str());
string path = topdir + "/wrap/tests"; string path = topdir + "/wrap/tests";
Module module(path.c_str(), "testWrap1",enable_verbose); Module module(path.c_str(), "testDependencies",enable_verbose);
CHECK_EXCEPTION(module.matlab_code("actual", "mexa64", "-O5"), DependencyMissing); CHECK_EXCEPTION(module.matlab_code("actual_deps", "mexa64", "-O5"), DependencyMissing);
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -72,8 +72,12 @@ TEST( wrap, parse ) {
EXPECT_LONGS_EQUAL(3, module.classes.size()); EXPECT_LONGS_EQUAL(3, module.classes.size());
// check using declarations // check using declarations
EXPECT_LONGS_EQUAL(1, module.using_namespaces.size()); strvec exp_using; exp_using += "geometry";
EXPECT(assert_equal("geometry", module.using_namespaces.front())); EXPECT(assert_equal(exp_using, module.using_namespaces));
// forward declarations
strvec exp_forward; exp_forward += "VectorNotEigen";
EXPECT(assert_equal(exp_forward, module.forward_declarations));
// check first class, Point2 // check first class, Point2
{ {