File: JoinPointModel.h

package info (click to toggle)
aspectc%2B%2B 1.0pre4~svn.20090918-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 117,308 kB
  • ctags: 410,601
  • sloc: cpp: 1,883,007; ansic: 17,279; sh: 2,190; makefile: 1,088
file content (279 lines) | stat: -rw-r--r-- 9,087 bytes parent folder | download | duplicates (2)
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
// This file is part of the AspectC++ compiler 'ac++'.
// Copyright (C) 1999-2003  The 'ac++' developers (see aspectc.org)
//                                                                
// This program 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 2 of 
// the License, or (at your option) any later version.            
//                                                                
// This program 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 this program; if not, write to the Free     
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
// MA  02111-1307  USA                                            

#ifndef __join_point_model_h__
#define __join_point_model_h__

#ifndef ACMODEL

#include <map>
#include <list>
#include <string>
using namespace std;

#include "JoinPointLoc.h"
#include "TUnitModelElementFactory.h"
#include "File.h"
#include "RepoXMLNode.h"
#include "RepoIdMgr.h"

using namespace Puma;

class PointCutExpr;

// This is just a simple container to manage the storage of join point
// location objects, which are used for scopes and world in the pointcut
// context

class JoinPointModel {
  IdElementMap _id_element_map;
  typedef list<JoinPointLoc*> JPLL;
  JPLL _elements;
  RepoIdMgr _id_mgr;
  JPL_Namespace *_root_namespace;
  list<File> _files;
  File *_tunit_file;
  TUnitModelElementFactory _factory;

  void register_entry (JoinPointLoc *loc, bool new_id = true) {
    _elements.push_back (loc);
    loc->map (&_id_element_map);
    if (new_id) {
      loc->id (_id_mgr.new_id ());
    }
    else
      _id_mgr.update (loc->id ());
  }
  
  void register_name (JPL_Name *jpl_name, bool new_id = true) {
    register_entry (jpl_name, new_id);
    if (jpl_name->is_root ()) _root_namespace = (JPL_Namespace*)jpl_name;
  }
  
  void unify (JoinPointLoc *tunit_loc);
  
  void register_tree (JoinPointLoc *loc);
  
  void reconcile (JPL_Name *tunit_name);

  void reconcile_children (JPL_Name *tunit_name, JPL_Name *prj_name);

  void copy_source_locs (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);

  bool equal_source_locs (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
  
  void reconcile (JoinPointModelElement *tunit_elem,
    JoinPointModelElement *prj_elem);

  void reconcile (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
  
  void clear ();

public:

  // file operation error codes
  enum FileOpResult{
    JPM_LOAD_ERR = -2, JPM_SAVE_ERR = -1, JPM_OK = 0 , JPM_VERSION = 1
  };

  // save the join point model in a file
  FileOpResult save (int fd, const string &filename);
  
  // discard the model and load new elements from a file
  FileOpResult load (int fd, const string &filename);
  
  // reconcile elements and IDs of the project join point model (this) and
  // a translation unit's join point
  void reconcile (JoinPointModel &tunit_jpm);
  
  // Result type for select ()
  typedef JPLL Selection;

  // constructor: initialize this model
  JoinPointModel () : _root_namespace (0), _tunit_file (0) {}
    
  // destructor: delete all stored join point locations
  ~JoinPointModel () { clear (); }

  // get the root namespace
  JPL_Namespace *root_namespace () const { return _root_namespace; }
  
  // select and return all join points of a given type (any of them)
  void select (JoinPointLoc::join_point_type jpt, Selection &result) {
    for (JPLL::iterator iter = _elements.begin (); iter != _elements.end ();
      ++iter) {
      JoinPointLoc::join_point_type curr_jpt = (*iter)->type ();
      if ((curr_jpt & jpt) != 0) {
        if (curr_jpt & (JoinPointLoc::Class | JoinPointLoc::Aspect)) {
          JPL_Class *jpl = (JPL_Class*)*iter;
          if (!jpl->intro_target ())
            continue;
        }
        result.push_back (*iter);
      }
    }
  }

  // default registration of a new element
  void register_elem (JoinPointLoc *jpl) {
    register_entry (jpl);
  }
  
  // specialized version of element registration for name join-points
  void register_elem (JPL_Name *jpl_name) {
    register_name (jpl_name);
  }

  File *register_file (const string &name, int len, bool is_tunit) {
    _files.push_back (File (name, len, is_tunit));
    File *new_file = &_files.back ();
    new_file->map (&_id_element_map);
    new_file->id (_id_mgr.new_id ()); 
    if (is_tunit)
      _tunit_file = new_file;
    return new_file;
  }
  
  // functions that are needed to create the model elements
  
  JPL_Namespace *new_namespace (JPL_Name *parent, const string &name) {
    // check if this namespace is already known
    if (parent) {
      JPL_Name *jpl = parent->lookup (name);
      if (jpl && jpl->type () == JoinPointLoc::Namespace)
        return (JPL_Namespace*)jpl; // it's known: return
    }
    else {
      if (root_namespace ())
        return root_namespace ();
    }
    // create a new namespace and register
    JPL_Namespace *new_elem = _factory.make_namespace (name);
    register_elem (new_elem);
    if (parent)
      new_elem->parent (parent);
    return new_elem;    
  }
  
  JPL_Function *new_function (JPL_Name *parent, const string &n, const string &s) {
    // check if the function is already known
    JPL_Name *jpl = parent->lookup (s);
    if (jpl && (jpl->type () == JoinPointLoc::Function))
      return (JPL_Function*)jpl;
    // create a new function and register
    JPL_Function *new_elem = _factory.make_function (n, s);
    register_elem (new_elem);
    new_elem->parent (parent);
    return new_elem;    
  }
  
  JPL_AdviceCode *new_advice_code (JPL_Name *parent, const string &n, const string &s) {
    // check if the advice code is already known
    JPL_Name *jpl = parent->lookup (s);
    if (jpl && (jpl->type () == JoinPointLoc::AdviceCode))
      return (JPL_AdviceCode*)jpl;
    // create a new advice code and register
    JPL_AdviceCode *new_elem = _factory.make_advice_code (n, s);
    register_elem (new_elem);
    new_elem->parent (parent);
    if (parent->type () == JoinPointLoc::Aspect) // TODO: use assert?
      ((JPL_Aspect*)parent)->advice_codes ().push_back (new_elem);
    return new_elem;    
  }
  
  JPL_Class *new_class (JPL_Name *parent, const string &name) {
    // check if the class is already known
    JPL_Name *jpl = parent->lookup (name);
    if (jpl && (jpl->type () == JoinPointLoc::Class))
      return (JPL_Class*)jpl;
    // create a new class and register
    JPL_Class *new_elem = _factory.make_class (name);
    register_elem (new_elem);
    new_elem->parent (parent);
    return new_elem;    
  }
  
  JPL_Aspect *new_aspect (JPL_Name *parent, const string &name) {
    // check if the aspect is already known
    JPL_Name *jpl = parent->lookup (name);
    if (jpl && (jpl->type () == JoinPointLoc::Aspect))
      return (JPL_Aspect*)jpl;
    // create a new class ans register
    JPL_Aspect *new_elem = _factory.make_aspect (name);
    register_elem (new_elem);
    new_elem->parent (parent);
    return new_elem;    
  }

  JPL_ClassSlice *new_class_slice (JPL_Name *parent, const string &name) {
    // check if this namespace is already known
    JPL_Name *jpl = parent->lookup (name);
    if (jpl && jpl->type () == JoinPointLoc::ClassSlice)
      return (JPL_ClassSlice*)jpl; // it's known: return
    // create a new namespace and register
    JPL_ClassSlice *new_elem = _factory.make_class_slice (name);
    register_elem (new_elem);
    new_elem->parent (parent);
    return new_elem;    
  }
  
  JPL_MethodCall *new_call (JPL_Function *target_func, int local_id) {
    JPL_MethodCall *new_elem = _factory.make_call ();
    new_elem->target_function (target_func);
    new_elem->lid (local_id);
    return new_elem;
  }
  
  JPL_Method *new_execution (JPL_Function *f) {
    JPL_Method *new_elem = _factory.make_execution ();
    new_elem->parent (f);
    return new_elem;
  }
  
  JPL_Construction *new_construction (JPL_Function *f) {
    JPL_Construction *new_elem = _factory.make_construction ();
    new_elem->parent (f);
    return new_elem;
  }
  
  JPL_Destruction *new_destruction (JPL_Function *f) {
    JPL_Destruction *new_elem = _factory.make_destruction ();
    new_elem->parent (f);
    return new_elem;
  }
  
  JPL_Type *new_type (const string &name) {
    return _factory.make_type (name);
  }
  
  // print the JoinPointModel
  void dump () const {
    cout << "=======" << endl;
    cout << "files:" << endl;
    for (list<File>::const_iterator i = _files.begin (); i != _files.end (); ++i)
      (*i).print (1);
    cout << "join points:" << endl;
    if (root_namespace ())
      root_namespace ()->dump ();
  }
  
};

#endif // !ACMODEL

#endif // __join_point_model_h__