summaryrefslogtreecommitdiff
path: root/src/lib/eolian_cxx/eo_validate.hh
blob: 8ffa7dccd7e5d5acb56000788f82b51bd1ed9804 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

#ifndef EOLIAN_CXX_EO_CLASS_VALIDATE_HH
#define EOLIAN_CXX_EO_CLASS_VALIDATE_HH

#include <algorithm>
#include <string>
#include <cassert>
#include <cstdlib>
#include "eo_types.hh"

#include <iostream>

namespace efl { namespace eolian {

inline bool
_is_valid(std::string const& value)
{
   return !value.empty() and (isalpha(value[0]) || value[0] == '_');
}

inline bool
_is_valid(eolian_type_instance const& type)
{
   // if (type.empty() || (*type.rbegin()).category == eolian_type::complex_)
   //   return false;
   for (auto rit = type.parts.rbegin(), last = type.parts.rend(); rit != last; ++rit)
     {
        if ((*rit).binding.empty() && (*rit).category == eolian_type::complex_)
            return false;
        // else if (rit != type.rbegin() && (*rit).category != eolian_type::complex_)
        //   {
        //     std::cout << "begin " << (rit != type.rbegin()) << std::endl;
        //     std::cout << "category " << rit->category << std::endl;
        //     return false;
        //   }
     }
   return true;
}

inline bool
_is_valid(parameters_container_type const& parameters)
{
   unsigned int n_callbacks = parameters_count_callbacks(parameters);
   return n_callbacks == 0 || n_callbacks == 1;
}

inline bool
_is_valid(events_container_type const& events)
{
   for (eo_event event : events)
     {
        if (event.name.empty() || event.eo_name.empty())
          return false;
     }
   return true;
}

template <typename T>
inline void
_validate(T const& val, eo_class const& cls)
{
   if(!_is_valid(val))
     {
        static_cast<void>(cls);
        assert(false && "Failed identifier validation");
     }
}

inline void
eo_class_validate(const eo_class& cls)
{
   // class name and type
   _validate(cls.name, cls);
   assert(cls.type == eo_class::regular_ ||
          cls.type == eo_class::regular_noninst_ ||
          cls.type == eo_class::interface_ ||
          cls.type == eo_class::mixin_);

   // constructors
   for (auto it = cls.constructors.cbegin(), last = cls.constructors.cend();
        it != last; ++it)
     {
        _validate((*it).name, cls);
        _validate((*it).params, cls);
        // parameters
        for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
             it_p != last_p; ++it_p)
          {
             _validate((*it_p).name, cls);
             _validate((*it_p).type, cls);
          }
     }
   // functions
   for (auto it = cls.functions.begin(), last  = cls.functions.end();
        it != last; ++it)
     {
        _validate((*it).name, cls);
        _validate((*it).impl, cls);
        _validate((*it).ret, cls);
        _validate((*it).params, cls);
        // parameters
        for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
             it_p != last_p; ++it_p)
          {
             _validate((*it_p).name, cls);
             _validate((*it_p).type, cls);
          }
     }
   // events
   _validate(cls.own_events, cls);
   _validate(cls.concrete_events, cls);
}

} } // namespace efl { namespace eolian {

#endif // EOLIAN_CXX_EO_CLASS_VALIDATE_HH