From 941a58db134ace1c7ae66ffc8f2a687d2e319a55 Mon Sep 17 00:00:00 2001
From: Jonathan Lambrechts <jonathan.lambrechts@uclouvain.be>
Date: Tue, 26 Jan 2010 09:50:08 +0000
Subject: [PATCH] dg : bindings documentation is complete (but quality is bad
 ...feel free to improve...)

---
 Common/BindingsTypeName.h                  | 158 -----------------
 Common/LuaBindings.cpp                     |  99 ++++++++---
 Common/LuaBindings.h                       | 188 ++++++++++++++++++---
 Geo/GModel.cpp                             |  14 ++
 Geo/MElement.cpp                           |  10 +-
 Geo/MVertex.cpp                            |  10 +-
 Numeric/fullMatrix.cpp                     |  13 +-
 Solver/dgConservationLaw.cpp               |  17 +-
 Solver/dgConservationLawAdvection.cpp      |  26 +--
 Solver/dgConservationLawAdvection.h        |  12 +-
 Solver/dgConservationLawPerfectGas.cpp     |  19 ++-
 Solver/dgConservationLawShallowWater2d.cpp |   7 +-
 Solver/dgConservationLawWaveEquation.cpp   |   9 +-
 Solver/dgSystemOfEquations.cpp             |  12 +-
 Solver/function.cpp                        |  10 +-
 Solver/luaFunction.cpp                     |   6 +-
 16 files changed, 368 insertions(+), 242 deletions(-)
 delete mode 100644 Common/BindingsTypeName.h

diff --git a/Common/BindingsTypeName.h b/Common/BindingsTypeName.h
deleted file mode 100644
index 0dab638b6a..0000000000
--- a/Common/BindingsTypeName.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef BINDINGS_TYPE_NAME_H
-#define BINDINGS_TYPE_NAME_H
-#include <vector>
-#include <string>
-/*** store a unique static class name for each binded class ***/
-template <typename type>
-class className{
-  static std::string _name;
-  public:
-  static void set(std::string name){
-    if(_name!=""){
-      throw;
-    }
-    _name=name;
-  }
-  static const std::string &get(){
-    if(_name==""){
-      throw;
-    }
-    return _name;
-  }
-};
-template<typename type>
-std::string  className<type>::_name;
-
-template <>
-class className<std::string>{
-  public:
-  static const std::string get(){
-    return "string";
-  }
-};
-template <>
-class className<int>{
-  public:
-  static const std::string get(){
-    return "int";
-  }
-};
-template <>
-class className<double>{
-  public:
-  static const std::string get(){
-    return "double";
-  }
-};
-template <>
-class className<void>{
-  public:
-  static const std::string get(){
-    return "void";
-  }
-};
-template <typename t>
-class className<t*>{
-  public:
-  static const std::string get(){
-    return className<t>::get();
-  }
-};
-template <typename t>
-class className<const t &>{
-  public:
-  static const std::string get(){
-    return className<t>::get();
-  }
-};
-
-template <typename cb>
-class argTypeNames;
-template <typename tr, typename tObj, typename t0, typename t1, typename t2, typename t3>
-class argTypeNames<tr (tObj::*)(t0,t1,t2,t3)>{
-  public:
-  static void get(std::vector<std::string> &names){
-    names.clear();
-    names.push_back(className<tr>::get());
-    names.push_back(className<t0>::get());
-    names.push_back(className<t1>::get());
-    names.push_back(className<t2>::get());
-    names.push_back(className<t3>::get());
-  }
-};
-template <typename tr, typename tObj, typename t0, typename t1, typename t2>
-class argTypeNames<tr (tObj::*)(t0,t1,t2)>{
-  public:
-  static void get(std::vector<std::string> &names){
-    names.clear();
-    names.push_back(className<tr>::get());
-    names.push_back(className<t0>::get());
-    names.push_back(className<t1>::get());
-    names.push_back(className<t2>::get());
-  }
-};
-template <typename tr, typename tObj, typename t0, typename t1>
-class argTypeNames<tr (tObj::*)(t0,t1)>{
-  public:
-  static void get(std::vector<std::string> &names){
-    names.clear();
-    names.push_back(className<tr>::get());
-    names.push_back(className<t0>::get());
-    names.push_back(className<t1>::get());
-  }
-};
-template <typename tr, typename tObj, typename t0>
-class argTypeNames<tr (tObj::*)(t0)>{
-  public:
-  static void get(std::vector<std::string> &names){
-    names.clear();
-    names.push_back(className<tr>::get());
-    names.push_back(className<t0>::get());
-  }
-};
-template <typename tr, typename tObj>
-class argTypeNames<tr (tObj::*)()>{
-  public:
-  static void get(std::vector<std::string> &names){
-    names.clear();
-    names.push_back(className<tr>::get());
-  }
-};
-template <typename cb>
-class argTypeNames;
-template <typename tr, typename tObj, typename t0, typename t1, typename t2, typename t3>
-class argTypeNames<tr (tObj::*)(t0,t1,t2,t3)const>{
-  public:
-  static void get(std::vector<std::string> &names){
-    argTypeNames<tr (tObj::*)(t0,t1,t2,t3)>::get(names);
-  }
-};
-template <typename tr, typename tObj, typename t0, typename t1, typename t2>
-class argTypeNames<tr (tObj::*)(t0,t1,t2)const>{
-  public:
-  static void get(std::vector<std::string> &names){
-    argTypeNames<tr (tObj::*)(t0,t1,t2)>::get(names);
-  }
-};
-template <typename tr, typename tObj, typename t0, typename t1>
-class argTypeNames<tr (tObj::*)(t0,t1)const>{
-  public:
-  static void get(std::vector<std::string> &names){
-    argTypeNames<tr (tObj::*)(t0,t1)>::get(names);
-  }
-};
-template <typename tr, typename tObj, typename t0>
-class argTypeNames<tr (tObj::*)(t0)const>{
-  public:
-  static void get(std::vector<std::string> &names){
-    argTypeNames<tr (tObj::*)(t0)>::get(names);
-  }
-};
-template <typename tr, typename tObj>
-class argTypeNames<tr (tObj::*)()const>{
-  public:
-  static void get(std::vector<std::string> &names){
-    argTypeNames<tr (tObj::*)()>::get(names);
-  }
-};
-#endif
diff --git a/Common/LuaBindings.cpp b/Common/LuaBindings.cpp
index 7a8dee96bd..ed38f5a956 100644
--- a/Common/LuaBindings.cpp
+++ b/Common/LuaBindings.cpp
@@ -27,7 +27,7 @@ extern "C" {
 #include "history.h"
 #endif
 
-static void report_errors(lua_State *L, int status)
+static void reportErrors(lua_State *L, int status)
 {
   if ( status!=0 ) {
     std::cerr << "-- " << lua_tostring(L, -1) << std::endl;
@@ -41,36 +41,40 @@ const char *colorBlue = "\033[1;34m";
 const char *colorDefault = "\033[0m";
 const char *colorBold = "\033[1m";
 
-static void print_method(std::string name, luaMethodBinding *mb, bool isConstructor=false) {
+static void printMethod(std::string name, luaMethodBinding *mb, bool isConstructor=false) {
   std::vector<std::string> argTypeNames;
   mb->getArgTypeNames(argTypeNames);
   std::cout<<"  ";
   if(!isConstructor)
     std::cout<<colorBold<<argTypeNames[0];
   std::cout<<colorBlue<<" "<<name<<colorDefault<<colorBold<<" (";
+  int count=0;
   for(int i=1;i< argTypeNames.size(); i++){
-    if(i!=1)
+    if(argTypeNames[i]=="-1")
+      continue;
+    if(count!=0)
       std::cout<<", ";
     std::cout<<colorBold<<argTypeNames[i]<<colorDefault;
-    if(mb->getArgNames().size()>i-1)
-      std::cout<<" "<<mb->getArgNames()[i-1];
+    if(mb->getArgNames().size()>count)
+      std::cout<<" "<<mb->getArgNames()[count];
+    count++;
   }
   std::cout<<colorBold<<")\n"<<colorDefault;
   const std::string description=mb->getDescription();
   std::cout<<(description.empty()?"no help available":description) <<"\n";
 
 }
-static void list_methods(classBinding *cb){
+static void listMethods(classBinding *cb){
   if(cb->methods.size())
     std::cout<<colorGreen<<"Methods from "<<cb->getClassName()<<colorDefault<<"\n";
   for(std::map<std::string,luaMethodBinding *>::iterator it = cb->methods.begin(); it!=cb->methods.end(); it++){
-    print_method(it->first,it->second);
+    printMethod(it->first,it->second);
   }
   if(cb->getParent())
-    list_methods(cb->getParent());
+    listMethods(cb->getParent());
 }
 
-static int lua_help (lua_State *L){
+static int luaHelp (lua_State *L){
   int argc = lua_gettop(L);
   binding *b = binding::instance();
   if (argc==0){
@@ -95,10 +99,10 @@ static int lua_help (lua_State *L){
     std::cout<<"\n";
     if(cb->getConstructor()){
       std::cout<<colorGreen<<"Constructor"<<colorDefault<<"\n";
-      print_method(className,cb->getConstructor(),true);
+      printMethod(className,cb->getConstructor(),true);
       std::cout<<"\n";
     }
-    list_methods(cb);
+    listMethods(cb);
     std::cout<<"\n";
     if(cb->children.size()){
       std::cout<<colorGreen<<"Children of "<<cb->getClassName()<<colorDefault<<"\n";
@@ -112,13 +116,15 @@ static int lua_help (lua_State *L){
   }
   return 0;
 }
+
+
 #ifdef HAVE_READLINE
-static int lua_save (lua_State *L){
+static int luaSave (lua_State *L){
   const char *filename = luaL_checkstring(L,1);
   write_history(filename);
   return 0;
 }
-static int lua_clear (lua_State *L){
+static int luaClear (lua_State *L){
   clear_history();
   return 0;
 }
@@ -126,20 +132,75 @@ static int lua_clear (lua_State *L){
 
 int binding::readFile(const char *filename)
 {
+  checkDocCompleteness();
   int s = luaL_loadfile(L, filename);
   if ( s==0 ) {
     Msg::Info("lua executes %s",filename);
     s = lua_pcall(L, 0, LUA_MULTRET, 0);
   }
-  report_errors(L, s);
+  reportErrors(L, s);
   lua_close(L);
   return (s==0);
 }
 
+static int countInArguments(const std::vector<std::string> &types){
+  int c=0;
+  for(int i=1;i<types.size();i++)
+    c+=(types[i]!="-1");
+  return c;
+}
+
+void binding::checkDocCompleteness(){
+  int nBad = 0;
+  for(std::map<std::string,classBinding *>::iterator cb = classes.begin(); cb!=classes.end();cb++) {
+    if(cb->second->getDescription().empty()){
+      Msg::Error("binded class %s has no description.", cb->first.c_str());
+      nBad++;
+    }
+    luaMethodBinding *constructor = cb->second->getConstructor();
+    if(constructor){
+      if(constructor->getDescription().empty()){
+        Msg::Error("binded constructor of class %s has no description.", cb->first.c_str());
+        nBad++;
+      }
+      std::vector<std::string> argTypeNames;
+      constructor->getArgTypeNames(argTypeNames);
+      int nTypeArg = countInArguments(argTypeNames);
+      int nDocArg = constructor->getArgNames().size();
+      if(nTypeArg != nDocArg){
+        Msg::Error("binded constructor of class %s takes %i arguments but %i are documented.",
+          cb->first.c_str(), nTypeArg, nDocArg);
+        nBad++;
+      }
+    }
+    for(std::map<std::string,luaMethodBinding*>::iterator mb = cb->second->methods.begin(); mb != cb->second->methods.end(); mb++){
+      if(mb->second->getDescription().empty()){
+        Msg::Error("binded method %s.%s has no description.", cb->first.c_str(),mb->first.c_str());
+        nBad++;
+      }
+      std::vector<std::string> argTypeNames;
+      mb->second->getArgTypeNames(argTypeNames);
+      int nTypeArg = countInArguments(argTypeNames);
+      int nDocArg = mb->second->getArgNames().size();
+      if(nTypeArg != nDocArg){
+        Msg::Error("binded method %s.%s takes %i arguments but %i are documented.",
+          cb->first.c_str(),mb->first.c_str(), nTypeArg, nDocArg);
+        nBad++;
+      }
+    }
+  }
+  if(nBad!=0){
+    Msg::Error("Bindings documentation is not complete (%i error(s) ). To enforce documentation completeness, I will exit now. Please complete the documentation and run gmsh again ;-) .\n",nBad);
+    exit(1);
+  }
+    
+}
+
 void binding::interactiveSession()
 {
   int lock = CTX::instance()->lock;
   CTX::instance()->lock = 0;
+  checkDocCompleteness();
 
   Msg::Info("Starting interactive lua session, press Ctrl-D to exit"); 
 #ifdef HAVE_READLINE
@@ -151,7 +212,7 @@ void binding::interactiveSession()
       std::cout<<expansion<<"\n";
     if(r==0 || r==1){
       add_history(expansion);
-      report_errors(L, luaL_dostring(L, expansion));
+      reportErrors(L, luaL_dostring(L, expansion));
     }
     if(expansion)
       free(expansion);
@@ -181,10 +242,10 @@ binding::binding(){
   luaopen_math(L);
   luaopen_debug(L);
 
-  lua_register(L,"help",lua_help);
+  lua_register(L,"help",luaHelp);
   #ifdef HAVE_READLINE
-  lua_register(L,"saveHistory",lua_save);
-  lua_register(L,"clearHistory",lua_clear);
+  lua_register(L,"saveHistory",luaSave);
+  lua_register(L,"clearHistory",luaClear);
   #endif
 
   // Register Lua bindings
@@ -196,7 +257,7 @@ binding::binding(){
   dgBoundaryCondition::registerBindings(this);
   dgConservationLawShallowWater2dRegisterBindings(this);
   dgConservationLawWaveEquationRegisterBindings(this);
-  dgConservationLawAdvectionRegisterBindings(this);
+  dgConservationLawAdvectionDiffusionRegisterBindings(this);
   dgPerfectGasLaw2dRegisterBindings(this);
   functionLua::registerBindings(this);
   function::registerDefaultFunctions();
diff --git a/Common/LuaBindings.h b/Common/LuaBindings.h
index f0e4c36e31..3ce1d041dc 100644
--- a/Common/LuaBindings.h
+++ b/Common/LuaBindings.h
@@ -9,16 +9,53 @@
 #include "Bindings.h"
 
 #ifdef HAVE_LUA
-#include "BindingsTypeName.h"
 
 extern "C" {
 #include "lua.h"
 #include "lauxlib.h"
 }
+/*** store a unique static class name for each binded class ***/
+template <typename type>
+class className{
+  static std::string _name;
+  public:
+  static void set(std::string name){
+    if(_name!=""){
+      throw;
+    }
+    _name=name;
+  }
+  static const std::string &get(){
+    if(_name==""){
+      throw;
+    }
+    return _name;
+  }
+};
+template<typename type>
+std::string  className<type>::_name;
+
+template <>
+template <typename t>
+class className<t*>{
+  public:
+  static const std::string get(){
+    return className<t>::get();
+  }
+};
+template <typename t>
+class className<const t &>{
+  public:
+  static const std::string get(){
+    return className<t>::get();
+  }
+};
+
 
 class classBinding;
 class binding {
   static binding *_instance;
+  void checkDocCompleteness();
   public:
   inline static binding *instance(){return _instance ? _instance : new binding();}
   lua_State *L;
@@ -30,18 +67,28 @@ class binding {
   classBinding *addClass(std::string className);
 };
 
+template <>
+class className<lua_State>{
+  public:
+  static const std::string get(){
+    return "-1";
+  }
+};
+
 
 
 /*** lua Stack : templates to get/push value from/on the lua stack ***/
 
 template<class type>
 class luaStack {
+};
+
+template <>
+class luaStack<void>
+{
   public:
-  static type get(lua_State *L, int ia){
-    Msg::Error("error cannot get generic class in lua, only pointers are implemented\n");
-  }
-  static void push(lua_State *L, type obj){
-    Msg::Error("cannot push generic class in lua, only pointers are implemented\n");
+  static std::string getName(){
+    return "void";
   }
 };
 
@@ -51,8 +98,8 @@ class luaStack<lua_State *>{
   static lua_State *get(lua_State *L, int ia){
     return L;
   }
-  static void push(lua_State *L, int i){
-    Msg::Error("error cannot push a lua_State in lua\n");
+  static std::string getName(){
+    return "-1";
   }
 };
 
@@ -66,6 +113,9 @@ class luaStack<int>{
   static void push(lua_State *L, int i){
     lua_pushinteger(L,i);
   }
+  static std::string getName(){
+    return "int";
+  }
 };
 
 template<class type>
@@ -83,7 +133,9 @@ class luaStack<std::vector<type > >{
     }
     return v;
   }
-  static void push(lua_State *L, std::vector<type> a){
+  static std::string getName(){
+    std::string name="vector of ";
+    return name+luaStack<type>::getName();
   }
 };
 
@@ -96,6 +148,9 @@ class luaStack<double>{
   static void push(lua_State *L, double v){
     lua_pushnumber(L,v);
   }
+  static std::string getName(){
+    return "double";
+  }
 };
 
 template<>
@@ -107,6 +162,9 @@ class luaStack<std::string>{
   static void push(lua_State *L, std::string s){
     lua_pushstring(L,s.c_str());
   }
+  static std::string getName(){
+    return "string";
+  }
 };
 
 template <typename type>
@@ -124,6 +182,9 @@ class luaStack<type *>{
     luaL_getmetatable(L,className<type>::get().c_str());  // lookup metatable in Lua registry
     lua_setmetatable(L, -2);
   }
+  static std::string getName(){
+    return className<type>::get();
+  }
 };
 template <typename type>
 class luaStack<const type *>{
@@ -140,6 +201,9 @@ class luaStack<const type *>{
     luaL_getmetatable(L,className<type>::get().c_str());  // lookup metatable in Lua registry
     lua_setmetatable(L, -2);
   }
+  static std::string getName(){
+    return className<type>::get();
+  }
 };
 
 template <typename type>
@@ -151,12 +215,8 @@ class luaStack<type &>{
     if(!ud) luaL_typerror(L, ia, className<type>::get().c_str());
     return *ud->pT; 
   }
-  static void push(lua_State *L,type &obj){
-/*    userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
-    ud->pT=&obj;
-    luaL_getmetatable(L,className<type>::get().c_str());  // lookup metatable in Lua registry
-    lua_setmetatable(L, -2);*/
-    Msg::Error("cannot push a reference lua\n");
+  static std::string getName(){
+    return className<type>::get();
   }
 };
 
@@ -169,12 +229,98 @@ class luaStack<const type &>{
     if(!ud) luaL_typerror(L, ia, className<type>::get().c_str());
     return *ud->pT; 
   }
-  static void push(lua_State *L,const type &obj){
-    /*userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
-    ud->pT=(type*)&obj;
-    luaL_getmetatable(L,className<type>::get().c_str());  // lookup metatable in Lua registry
-    lua_setmetatable(L, -2);*/
-    Msg::Error("cannot push a reference lua\n");
+  static std::string getName(){
+    return className<type>::get();
+  }
+};
+
+template <typename cb>
+class argTypeNames;
+template <typename tr, typename tObj, typename t0, typename t1, typename t2, typename t3>
+class argTypeNames<tr (tObj::*)(t0,t1,t2,t3)>{
+  public:
+  static void get(std::vector<std::string> &names){
+    names.clear();
+    names.push_back(luaStack<tr>::getName());
+    names.push_back(luaStack<t0>::getName());
+    names.push_back(luaStack<t1>::getName());
+    names.push_back(luaStack<t2>::getName());
+    names.push_back(luaStack<t3>::getName());
+  }
+};
+template <typename tr, typename tObj, typename t0, typename t1, typename t2>
+class argTypeNames<tr (tObj::*)(t0,t1,t2)>{
+  public:
+  static void get(std::vector<std::string> &names){
+    names.clear();
+    names.push_back(luaStack<tr>::getName());
+    names.push_back(luaStack<t0>::getName());
+    names.push_back(luaStack<t1>::getName());
+    names.push_back(luaStack<t2>::getName());
+  }
+};
+template <typename tr, typename tObj, typename t0, typename t1>
+class argTypeNames<tr (tObj::*)(t0,t1)>{
+  public:
+  static void get(std::vector<std::string> &names){
+    names.clear();
+    names.push_back(luaStack<tr>::getName());
+    names.push_back(luaStack<t0>::getName());
+    names.push_back(luaStack<t1>::getName());
+  }
+};
+template <typename tr, typename tObj, typename t0>
+class argTypeNames<tr (tObj::*)(t0)>{
+  public:
+  static void get(std::vector<std::string> &names){
+    names.clear();
+    names.push_back(luaStack<tr>::getName());
+    names.push_back(luaStack<t0>::getName());
+  }
+};
+template <typename tr, typename tObj>
+class argTypeNames<tr (tObj::*)()>{
+  public:
+  static void get(std::vector<std::string> &names){
+    names.clear();
+    names.push_back(luaStack<tr>::getName());
+  }
+};
+template <typename cb>
+class argTypeNames;
+template <typename tr, typename tObj, typename t0, typename t1, typename t2, typename t3>
+class argTypeNames<tr (tObj::*)(t0,t1,t2,t3)const>{
+  public:
+  static void get(std::vector<std::string> &names){
+    argTypeNames<tr (tObj::*)(t0,t1,t2,t3)>::get(names);
+  }
+};
+template <typename tr, typename tObj, typename t0, typename t1, typename t2>
+class argTypeNames<tr (tObj::*)(t0,t1,t2)const>{
+  public:
+  static void get(std::vector<std::string> &names){
+    argTypeNames<tr (tObj::*)(t0,t1,t2)>::get(names);
+  }
+};
+template <typename tr, typename tObj, typename t0, typename t1>
+class argTypeNames<tr (tObj::*)(t0,t1)const>{
+  public:
+  static void get(std::vector<std::string> &names){
+    argTypeNames<tr (tObj::*)(t0,t1)>::get(names);
+  }
+};
+template <typename tr, typename tObj, typename t0>
+class argTypeNames<tr (tObj::*)(t0)const>{
+  public:
+  static void get(std::vector<std::string> &names){
+    argTypeNames<tr (tObj::*)(t0)>::get(names);
+  }
+};
+template <typename tr, typename tObj>
+class argTypeNames<tr (tObj::*)()const>{
+  public:
+  static void get(std::vector<std::string> &names){
+    argTypeNames<tr (tObj::*)()>::get(names);
   }
 };
 
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index dadb44e429..ac28226d9d 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1351,13 +1351,27 @@ void GModel::save(std::string fileName)
 void GModel::registerBindings(binding *b)
 {
   classBinding *cb = b->addClass<GModel>("GModel");
+  cb->setDescription("A GModel contains a geometrycal and it's mesh.");
   methodBinding *cm;
   cm = cb->addMethod("mesh", &GModel::mesh);
+  cm->setArgNames("dim",NULL);
+  cm->setDescription("Generate a mesh of this model in dimension 'dim'.");
   cm = cb->addMethod("load", &GModel::load);
+  cm->setDescription("Merge the file 'filename' in this model, the file can be in any format (guessed from the extension) known by gmsh.");
+  cm->setArgNames("filename",NULL);
   cm = cb->addMethod("save", &GModel::save);
+  cm->setDescription("Save this model in the file 'filename'. The content of the file depends on the format (guessed from the extension).");
+  cm->setArgNames("filename",NULL);
   cm = cb->addMethod("getNumMeshElements",(int (GModel::*)()) &GModel::getNumMeshElements);
+  cm->setDescription("return the number of mesh elemnts in the model");
   cm = cb->addMethod("getMeshElementByTag",&GModel::getMeshElementByTag);
+  cm->setArgNames("tag",NULL);
+  cm->setDescription("access a mesh element by tag, using the element cache");
   cm = cb->addMethod("getNumMeshVertices",&GModel::getNumMeshVertices);
+  cm->setDescription("return the total number of vertices in the mesh");
   cm = cb->addMethod("getMeshVertexByTag",&GModel::getMeshVertexByTag);
+  cm->setDescription("access a mesh vertex by tag, using the vertex cache");
+  cm->setArgNames("tag",NULL);
   cm = cb->setConstructor<GModel>();
+  cm->setDescription("Create an empty GModel.");
 }
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index be20d7389b..197322bdda 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -807,13 +807,21 @@ MElement *MElementFactory::create(int type, std::vector<MVertex*> &v,
 void MElement::registerBindings(binding *b)
 {
   classBinding *cb = b->addClass<MElement>("MElement");
+  cb->setDescription("A mesh element.");
   methodBinding *cm;
   cm = cb->addMethod("getNum",&MElement::getNum);
-  // here we specify the cast because there are 2 MVertex::x function
+  cm->setDescription("return the tag of the element");
   cm = cb->addMethod("getNumVertices", &MElement::getNumVertices);
+  cm->setDescription("get the number of vertices of this element");
   cm = cb->addMethod("getVertex", &MElement::getVertex);
+  cm->setDescription("return the i-th vertex of this element");
+  cm->setArgNames("i",NULL);
   cm = cb->addMethod("getType", &MElement::getType);
+  cm->setDescription("get the type of the element");
   cm = cb->addMethod("getPartition", &MElement::getPartition);
+  cm->setDescription("get the partition to which the element belongs");
   cm = cb->addMethod("getPolynomialOrder", &MElement::getPolynomialOrder);
+  cm->setDescription("return the polynomial order the element");
   cm = cb->addMethod("getDim", &MElement::getDim);
+  cm->setDescription("return the geometrical dimension of the element");
 }
diff --git a/Geo/MVertex.cpp b/Geo/MVertex.cpp
index c0e19b44e5..69a3ca1315 100644
--- a/Geo/MVertex.cpp
+++ b/Geo/MVertex.cpp
@@ -403,12 +403,18 @@ bool reparamMeshVertexOnEdge(const MVertex *v, const GEdge *ge, double &param)
 void MVertex::registerBindings(binding *b)
 {
   classBinding *cb = b->addClass<MVertex>("MVertex");
+  cb->setDescription("A mesh vertex.");
   methodBinding *cm;
   cm = cb->addMethod("getNum",&MVertex::getNum);
-  // here we specify the cast because there are 2 MVertex::x function
+  cm->setDescription("Return the immutable vertex number.");
+  //the cast is epxlicitely given because there are 2 MVertex::x function
   cm = cb->addMethod("x", (double (MVertex::*)() const) &MVertex::x);
-  // cm = cb->addMethod("x2", (double& (MVertex::*)()) &MVertex::x);
+  cm->setDescription("Return the x-coordinate.");
   cm = cb->addMethod("y", (double (MVertex::*)() const) &MVertex::y);
+  cm->setDescription("Return the y-coordinate.");
   cm = cb->addMethod("z", (double (MVertex::*)() const) &MVertex::z);
+  cm->setDescription("Return the z-coordinate.");
   cm = cb->setConstructor<MVertex,double,double,double>();
+  cm->setArgNames("x","y","z",NULL);
+  cm->setDescription("Create a new mesh vertex at (x,y,z).");
 }
diff --git a/Numeric/fullMatrix.cpp b/Numeric/fullMatrix.cpp
index 865a4b41e8..e799a67efa 100644
--- a/Numeric/fullMatrix.cpp
+++ b/Numeric/fullMatrix.cpp
@@ -293,17 +293,22 @@ template<>
 void fullMatrix<double>::registerBindings(binding *b)
 {
   classBinding *cb = b->addClass<fullMatrix<double> >("fullMatrix");
+  cb->setDescription("A full matrix of double-precision floating point numbers. The memory is allocated in one continuous block and stored in column major order (like in fortran).");
   methodBinding *cm;
   cm = cb->addMethod("size1", &fullMatrix<double>::size1);
-  cm->setDescription("return the number of rows in the matrix");
+  cm->setDescription("Returns the number of rows in the matrix");
   cm = cb->addMethod("size2", &fullMatrix<double>::size2);
-  cm->setDescription("return the number of columns in the matrix");
+  cm->setDescription("Returns the number of columns in the matrix");
   cm = cb->addMethod("get", &fullMatrix<double>::get);
   cm->setArgNames("i","j",NULL);
-  cm->setDescription("return the (i,j) entry of the matrix");
+  cm->setDescription("Returns the (i,j) entry of the matrix");
   cm = cb->addMethod("set", &fullMatrix<double>::set);
   cm->setArgNames("i","j","v",NULL);
-  cm->setDescription("set the (i,j) entry of the matrix to v");
+  cm->setDescription("Sets the (i,j) entry of the matrix to v");
   cm = cb->addMethod("gemm", &fullMatrix<double>::gemm);
+  cm->setArgNames("A","B","alpha","beta",NULL);
+  cm->setDescription("this = beta*this + alpha * (A.B)");
   cm = cb->setConstructor<fullMatrix<double>,int,int>();
+  cm->setDescription ("A new matrix of size 'nRows' x 'nColumns'");
+  cm->setArgNames("nRows","nColumns",NULL);
 }
diff --git a/Solver/dgConservationLaw.cpp b/Solver/dgConservationLaw.cpp
index ac1f210841..19eb442167 100644
--- a/Solver/dgConservationLaw.cpp
+++ b/Solver/dgConservationLaw.cpp
@@ -151,12 +151,21 @@ dataCacheDouble *dgBoundaryCondition::newDiffusiveNeumannBC(dataCacheMap &cacheM
 
 void dgConservationLaw::registerBindings(binding *b){
   classBinding *cb = b->addClass<dgConservationLaw>("dgConservationLaw");
-  cb->addMethod("addBoundaryCondition",&dgConservationLaw::addBoundaryCondition);
-  cb->addMethod("new0FluxBoundary",&dgConservationLaw::new0FluxBoundary);
-  cb->addMethod("newSymmetryBoundary",&dgConservationLaw::newSymmetryBoundary);
-  cb->addMethod("newOutsideValueBoundary",&dgConservationLaw::newOutsideValueBoundary);
+  cb->setDescription("A conservation law is defined a convective flux (f), a diffusive flux(g), a source term(r) and a set of boundary conditions.\n\\partial_t L(u) =   \\nabla \\cdot (\\vec{f}(u,forcings)) + \\nabla \\cdot (\\vec{g}(u,\\nabla u,forcings) + r(u,forcings).");
+  methodBinding *cm;
+  cm = cb->addMethod("addBoundaryCondition",&dgConservationLaw::addBoundaryCondition);
+  cm->setDescription("Use the boundary condition 'bc' for interface tagged with 'tag',");
+  cm->setArgNames("tag","bc",NULL);
+  cm = cb->addMethod("new0FluxBoundary",&dgConservationLaw::new0FluxBoundary);
+  cm->setDescription("Create a new boundary condition which set to 0 all the fluxes through the interfaces.");
+  cm = cb->addMethod("newSymmetryBoundary",&dgConservationLaw::newSymmetryBoundary);
+  cm->setDescription("Create a new boundary condition using the values computed inside the domain as boundary values. (In practice, the fluxes are computed with the Riemann solver of this equation using the internal values as internal AND external values.)");
+  cm = cb->addMethod("newOutsideValueBoundary",&dgConservationLaw::newOutsideValueBoundary);
+  cm->setDescription("Create a new boundary condition which compute the fluxes using the Riemann solver using the 'outsideFunction' function to compute external values.");
+  cm->setArgNames("outsideFunction",NULL);
 }
 
 void dgBoundaryCondition::registerBindings(binding *b){
   classBinding *cb = b->addClass<dgBoundaryCondition>("dgBoundaryCondition");
+  cb->setDescription("A boundary condition of a conservation law. Boundary conditions should be associated with tag using dgConservationLaw::addBoundaryCondition.");
 }
diff --git a/Solver/dgConservationLawAdvection.cpp b/Solver/dgConservationLawAdvection.cpp
index 0217e94128..45e6176814 100644
--- a/Solver/dgConservationLawAdvection.cpp
+++ b/Solver/dgConservationLawAdvection.cpp
@@ -6,7 +6,7 @@
 #include "function.h"
 #include "dgConservationLawAdvection.h"
 
-class dgConservationLawAdvection::advection : public dataCacheDouble {
+class dgConservationLawAdvectionDiffusion::advection : public dataCacheDouble {
   dataCacheDouble &sol, &v;
   public:
   advection(std::string vFunctionName, dataCacheMap &cacheMap):
@@ -22,7 +22,7 @@ class dgConservationLawAdvection::advection : public dataCacheDouble {
     }
   }
 };
-class dgConservationLawAdvection::riemann : public dataCacheDouble {
+class dgConservationLawAdvectionDiffusion::riemann : public dataCacheDouble {
   dataCacheDouble &normals, &solLeft, &solRight,&v;
   public:
   riemann(std::string vFunctionName, dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight):
@@ -45,7 +45,7 @@ class dgConservationLawAdvection::riemann : public dataCacheDouble {
     }
   }
 };
-class dgConservationLawAdvection::diffusion : public dataCacheDouble {
+class dgConservationLawAdvectionDiffusion::diffusion : public dataCacheDouble {
   dataCacheDouble &solgrad, &nu;
   public:
   diffusion(std::string nuFunctionName, dataCacheMap &cacheMap):
@@ -63,31 +63,31 @@ class dgConservationLawAdvection::diffusion : public dataCacheDouble {
     }
   }
 };
-dataCacheDouble *dgConservationLawAdvection::newConvectiveFlux( dataCacheMap &cacheMap) const {
+dataCacheDouble *dgConservationLawAdvectionDiffusion::newConvectiveFlux( dataCacheMap &cacheMap) const {
   if( !_vFunctionName.empty())
     return new advection(_vFunctionName,cacheMap);
   else
     return NULL;
 }
-dataCacheDouble *dgConservationLawAdvection::newMaximumDiffusivity( dataCacheMap &cacheMap) const {
+dataCacheDouble *dgConservationLawAdvectionDiffusion::newMaximumDiffusivity( dataCacheMap &cacheMap) const {
   if( !_nuFunctionName.empty())
     return &cacheMap.get(_nuFunctionName);
   else
     return NULL;
 }
-dataCacheDouble *dgConservationLawAdvection::newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const {
+dataCacheDouble *dgConservationLawAdvectionDiffusion::newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const {
   if( !_vFunctionName.empty())
     return new riemann(_vFunctionName,cacheMapLeft, cacheMapRight);
   else
     return NULL;
 }
-dataCacheDouble *dgConservationLawAdvection::newDiffusiveFlux( dataCacheMap &cacheMap) const {
+dataCacheDouble *dgConservationLawAdvectionDiffusion::newDiffusiveFlux( dataCacheMap &cacheMap) const {
   if( !_nuFunctionName.empty())
     return new diffusion(_nuFunctionName,cacheMap);
   else
     return NULL;
 }
-dgConservationLawAdvection::dgConservationLawAdvection(std::string vFunctionName, std::string nuFunctionName) 
+dgConservationLawAdvectionDiffusion::dgConservationLawAdvectionDiffusion(std::string vFunctionName, std::string nuFunctionName) 
 {
   _vFunctionName = vFunctionName;
   _nuFunctionName = nuFunctionName;
@@ -95,8 +95,12 @@ dgConservationLawAdvection::dgConservationLawAdvection(std::string vFunctionName
 }
 
 #include "Bindings.h"
-void dgConservationLawAdvectionRegisterBindings (binding *b){
-  classBinding *cb = b->addClass<dgConservationLawAdvection>("dgConservationLawAdvection");
-  cb->setConstructor<dgConservationLawAdvection,std::string,std::string>();
+void dgConservationLawAdvectionDiffusionRegisterBindings (binding *b){
+  classBinding *cb = b->addClass<dgConservationLawAdvectionDiffusion>("dgConservationLawAdvectionDiffusion");
+  methodBinding *cm;
+  cm = cb->setConstructor<dgConservationLawAdvectionDiffusion,std::string,std::string>();
+  cm->setArgNames("v","nu",NULL);
+  cm->setDescription("A new advection-diffusion law. The advection speed is given by 'v' vector function and the (scalar) diffusivity is given by the function 'nu'.");
   cb->setParentClass<dgConservationLaw>();
+  cb->setDescription("Advection and diffusion of a scalar, the advection and diffusion are provided by functions.");
 }
diff --git a/Solver/dgConservationLawAdvection.h b/Solver/dgConservationLawAdvection.h
index 1251f992b0..32f6fa58dd 100644
--- a/Solver/dgConservationLawAdvection.h
+++ b/Solver/dgConservationLawAdvection.h
@@ -1,9 +1,9 @@
-#ifndef _DG_CONSERVATION_LAW_ADVECTION_H
-#define _DG_CONSERVATION_LAW_ADVECTION_H
+#ifndef _DG_CONSERVATION_LAW_ADVECTION_DIFFUSION_H
+#define _DG_CONSERVATION_LAW_ADVECTION_DIFFUSION_H
 #include "dgConservationLaw.h"
-//Advection diffusion equation
+//AdvectionDiffusion diffusion equation
 //dc/dt + v div(c) - nu lapl(c) = 0
-class dgConservationLawAdvection : public dgConservationLaw {
+class dgConservationLawAdvectionDiffusion : public dgConservationLaw {
   std::string _vFunctionName,_nuFunctionName;
   class advection;
   class riemann;
@@ -13,8 +13,8 @@ class dgConservationLawAdvection : public dgConservationLaw {
   dataCacheDouble *newMaximumDiffusivity( dataCacheMap &cacheMap) const;
   dataCacheDouble *newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const;
   dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const;
-  dgConservationLawAdvection(std::string vFunctionName, std::string nuFunctionName);
+  dgConservationLawAdvectionDiffusion(std::string vFunctionName, std::string nuFunctionName);
 };
 class binding;
-void dgConservationLawAdvectionRegisterBindings (binding *b);
+void dgConservationLawAdvectionDiffusionRegisterBindings (binding *b);
 #endif
diff --git a/Solver/dgConservationLawPerfectGas.cpp b/Solver/dgConservationLawPerfectGas.cpp
index fcad55ee40..9eac309d43 100644
--- a/Solver/dgConservationLawPerfectGas.cpp
+++ b/Solver/dgConservationLawPerfectGas.cpp
@@ -848,12 +848,19 @@ dgBoundaryCondition *dgPerfectGasLaw2d::newSlipWallBoundary()  {
 #include "Bindings.h"
 void dgPerfectGasLaw2dRegisterBindings (binding *b){
   classBinding *cb = b->addClass<dgPerfectGasLaw2d>("dgPerfectGasLaw2d");
+  cb->setDescription("Perfect Gas conservation law\n\\rho \\left(\\frac{\\partial \\mathbf{v}}{\\partial t} + \\mathbf{v} \\cdot \\nabla \\mathbf{v}\\right) = -\\nabla p + \\mu \\nabla^2 \\mathbf{v} + \\left( \\tfrac13 \\mu + \\mu^v) \\nabla (\\nabla \\cdot \\mathbf{v} \\right) + \\rho \\mathbf{f}"); 
   methodBinding *cm;
-  cb->addMethod("newWallBoundary",&dgPerfectGasLaw2d::newWallBoundary);
-  cb->addMethod("newNonSlipWallBoundary",&dgPerfectGasLaw2d::newWallBoundary);
-  cb->addMethod("newSlipWallBoundary",&dgPerfectGasLaw2d::newSlipWallBoundary);
-  cb->addMethod("setSource",&dgPerfectGasLaw2d::setSource);
-  cb->addMethod("setViscosityAndThermalConductivity",&dgPerfectGasLaw2d::setViscosityAndThermalConductivity);
-  cb->setConstructor<dgPerfectGasLaw2d>();
+  cm = cb->addMethod("newNonSlipWallBoundary",&dgPerfectGasLaw2d::newWallBoundary);
+  cm->setDescription("non slip wall");
+  cm = cb->addMethod("newSlipWallBoundary",&dgPerfectGasLaw2d::newSlipWallBoundary);
+  cm->setDescription("slip wall");
+  cm = cb->addMethod("setSource",&dgPerfectGasLaw2d::setSource);
+  cm->setArgNames("f",NULL);
+  cm->setDescription("set the function to compute the source term");
+  cm = cb->addMethod("setViscosityAndThermalConductivity",&dgPerfectGasLaw2d::setViscosityAndThermalConductivity);
+  cm->setArgNames("f_mu","f_kappa",NULL);
+  cm->setDescription("set the fonctions to compute mu and kappa, the scalar viscosity and thermal conductivity coefficients");
+  cm = cb->setConstructor<dgPerfectGasLaw2d>();
+  cm->setDescription("A new perfect gas conservation law");
   cb->setParentClass<dgConservationLaw>();
 }
diff --git a/Solver/dgConservationLawShallowWater2d.cpp b/Solver/dgConservationLawShallowWater2d.cpp
index 7fef3c89e6..0671ba0217 100644
--- a/Solver/dgConservationLawShallowWater2d.cpp
+++ b/Solver/dgConservationLawShallowWater2d.cpp
@@ -147,8 +147,11 @@ dgBoundaryCondition *dgConservationLawShallowWater2d::newBoundaryWall(){
 #include "Bindings.h"
 void dgConservationLawShallowWater2dRegisterBindings (binding *b){
   classBinding *cb = b->addClass<dgConservationLawShallowWater2d>("dgConservationLawShallowWater2d");
+  cb->setDescription("The conservative sallow water conservation law. (H, Hu, Hv)");
   methodBinding *cm;
-  cb->addMethod("newBoundaryWall",&dgConservationLawShallowWater2d::newBoundaryWall);
-  cb->setConstructor<dgConservationLawShallowWater2d>();
+  cm = cb->addMethod("newBoundaryWall",&dgConservationLawShallowWater2d::newBoundaryWall);
+  cm->setDescription("slip wall boundary");
+  cm = cb->setConstructor<dgConservationLawShallowWater2d>();
+  cm->setDescription("A new shallow water conservation law.");
   cb->setParentClass<dgConservationLaw>();
 }
diff --git a/Solver/dgConservationLawWaveEquation.cpp b/Solver/dgConservationLawWaveEquation.cpp
index 61f7fe076e..9a8c9d8c63 100644
--- a/Solver/dgConservationLawWaveEquation.cpp
+++ b/Solver/dgConservationLawWaveEquation.cpp
@@ -140,8 +140,13 @@ dgBoundaryCondition *dgConservationLawWaveEquation::newBoundaryWall(){
 #include "Bindings.h"
 void dgConservationLawWaveEquationRegisterBindings(binding *b){
   classBinding *cb = b->addClass<dgConservationLawWaveEquation> ("dgConservationLawWaveEquation");
+  cb->setDescription("Solve the wave equation in dimension 1, 2 or 3.)");
   methodBinding *cm;
-  cb->addMethod("newBoundaryWall",&dgConservationLawWaveEquation::newBoundaryWall);
-  cb->setConstructor<dgConservationLawWaveEquation,int>();
+  cm = cb->addMethod("newBoundaryWall",&dgConservationLawWaveEquation::newBoundaryWall);
+  cm->setDescription("wall boundary");
+  cm = cb->setConstructor<dgConservationLawWaveEquation,int>();
+  cm->setArgNames("d",NULL);
+  cm->setDescription("New wave equation of dimension 'd'");
+
   cb->setParentClass<dgConservationLaw>();
 }
diff --git a/Solver/dgSystemOfEquations.cpp b/Solver/dgSystemOfEquations.cpp
index d036a13ea8..68cfdb03a5 100644
--- a/Solver/dgSystemOfEquations.cpp
+++ b/Solver/dgSystemOfEquations.cpp
@@ -49,8 +49,10 @@ static dgSystemOfEquations *myConstructorPtr(GModel* gm){
 void dgSystemOfEquations::registerBindings(binding *b) {
   classBinding *cb = b->addClass<dgSystemOfEquations>("dgSystemOfEquations");
   cb->setDescription("a class to rule them all :-) -- bad description, this class will be removed anyway");
-  cb->setConstructor<dgSystemOfEquations,GModel*>();
   methodBinding *cm;
+  cm = cb->setConstructor<dgSystemOfEquations,GModel*>();
+  cm->setArgNames("model",NULL);
+  cm->setDescription("A new system of equation on the domain described by 'model'");
   cm = cb->addMethod("setConservationLaw",&dgSystemOfEquations::setConservationLaw);
   cm->setArgNames("law",NULL);
   cm->setDescription("set the conservation law this system solves");
@@ -63,9 +65,11 @@ void dgSystemOfEquations::registerBindings(binding *b) {
   cm->setArgNames("functionName",NULL);
   cm->setDescription("project the function \"functionName\" on the solution vector");
   cm = cb->addMethod("RK44",&dgSystemOfEquations::RK44);
+  cm->setArgNames("dt",NULL);
+  cm->setDescription("Do a runge-kuta temporal iteration with 4 sub-steps and a precision order of 4 with a time step \"dt\". This function returns the sum of the nodal residuals.");
   cm = cb->addMethod("ForwardEuler",&dgSystemOfEquations::ForwardEuler);
-  cm->setArgNames("norm","dt",NULL);
-  cm->setDescription("do a runge-kuta temporal iteration with a time step \"dt\" and return the sum of the nodal residuals");
+  cm->setArgNames("dt",NULL);
+  cm->setDescription("do a forward euler temporal iteration with a time step \"dt\" and return the sum of the nodal residuals");
   cm = cb->addMethod("setOrder",&dgSystemOfEquations::setOrder);
   cm->setArgNames("order",NULL);
   cm->setDescription("set the polynpolynomialomial order of the lagrange shape functions");
@@ -77,6 +81,8 @@ void dgSystemOfEquations::registerBindings(binding *b) {
   cm->setArgNames("dt",NULL);
   cm->setDescription("do one RK44 time step with the slope limiter (only for p=1)");
   cm = cb->addMethod("multirateRK43",&dgSystemOfEquations::multirateRK43);
+  cm->setArgNames("dt",NULL);
+  cm->setDescription("Do a runge-kuta temporal iteration with 4 sub-steps and a precision order of 3 using different time-step depending on the element size. This function returns the sum of the nodal residuals.");
   cm = cb->addMethod("saveSolution",&dgSystemOfEquations::saveSolution);
   cm->setArgNames("filename",NULL);
   cm->setDescription("dump the solution in binary format");
diff --git a/Solver/function.cpp b/Solver/function.cpp
index 998d8358d5..661611d72e 100644
--- a/Solver/function.cpp
+++ b/Solver/function.cpp
@@ -189,9 +189,15 @@ void function::registerDefaultFunctions()
 }
 void function::registerBindings(binding *b){
   classBinding *cb = b->addClass<function>("function");
-  cb->addMethod("getName",&function::getName);
+  cb->setDescription("A generic function that can be evaluated on a set of points. Functions can call other functions and their values are cached so that if two different functions call the same function f, f is only evaluated once.");
+  methodBinding *mb;
+  mb = cb->addMethod("getName",&function::getName);
+  mb->setDescription("Return the string which identifies this function.");
   cb = b->addClass<functionConstant>("functionConstant");
-  cb->setConstructor<functionConstant,fullMatrix<double>*>();
+  cb->setDescription("A constant (scalar or vector) function");
+  mb = cb->setConstructor<functionConstant,fullMatrix<double>*>();
+  mb->setArgNames("v",NULL);
+  mb->setDescription("A new constant function wich values 'v' everywhere. v can be a row-vector.");
   cb->setParentClass<function>();
 }
 
diff --git a/Solver/luaFunction.cpp b/Solver/luaFunction.cpp
index c0518cadef..ba1225216a 100644
--- a/Solver/luaFunction.cpp
+++ b/Solver/luaFunction.cpp
@@ -48,7 +48,11 @@ dataCacheDouble *functionLua::newDataCache(dataCacheMap *m)
 
 void functionLua::registerBindings(binding *b){
   classBinding *cb= b->addClass<functionLua>("functionLua");
-  cb->setConstructor<functionLua,int,std::string,std::vector<std::string>,lua_State*>();
+  cb->setDescription("A function (see the 'function' documentation entry) defined in LUA.");
+  methodBinding *mb;
+  mb = cb->setConstructor<functionLua,int,std::string,std::vector<std::string>,lua_State*>();
+  mb->setArgNames("d", "f", "dep", NULL);
+  mb->setDescription("A new functionLua which evaluates a vector of dimension 'd' using the lua function 'f'. This function can take other functions as arguments listed by the 'dep' vector.");
   cb->setParentClass<function>();
 }
 
-- 
GitLab