1
// This file is part of the AspectC++ compiler 'ac++'.
2
// Copyright (C) 1999-2003 The 'ac++' developers (see aspectc.org)
4
// This program is free software; you can redistribute it and/or
5
// modify it under the terms of the GNU General Public License as
6
// published by the Free Software Foundation; either version 2 of
7
// the License, or (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public
15
// License along with this program; if not, write to the Free
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
#ifndef __join_point_model_h__
20
#define __join_point_model_h__
29
#include "JoinPointLoc.h"
30
#include "TUnitModelElementFactory.h"
32
#include "RepoXMLNode.h"
33
#include "RepoIdMgr.h"
39
// This is just a simple container to manage the storage of join point
40
// location objects, which are used for scopes and world in the pointcut
43
class JoinPointModel {
44
IdElementMap _id_element_map;
45
typedef list<JoinPointLoc*> JPLL;
48
JPL_Namespace *_root_namespace;
51
TUnitModelElementFactory _factory;
53
void register_entry (JoinPointLoc *loc, bool new_id = true) {
54
_elements.push_back (loc);
55
loc->map (&_id_element_map);
57
loc->id (_id_mgr.new_id ());
60
_id_mgr.update (loc->id ());
63
void register_name (JPL_Name *jpl_name, bool new_id = true) {
64
register_entry (jpl_name, new_id);
65
if (jpl_name->is_root ()) _root_namespace = (JPL_Namespace*)jpl_name;
68
void unify (JoinPointLoc *tunit_loc);
70
void register_tree (JoinPointLoc *loc);
72
void reconcile (JPL_Name *tunit_name);
74
void reconcile_children (JPL_Name *tunit_name, JPL_Name *prj_name);
76
void copy_source_locs (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
78
bool equal_source_locs (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
80
void reconcile (JoinPointModelElement *tunit_elem,
81
JoinPointModelElement *prj_elem);
83
void reconcile (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
89
// file operation error codes
91
JPM_LOAD_ERR = -2, JPM_SAVE_ERR = -1, JPM_OK = 0 , JPM_VERSION = 1
94
// save the join point model in a file
95
FileOpResult save (int fd, const string &filename);
97
// discard the model and load new elements from a file
98
FileOpResult load (int fd, const string &filename);
100
// reconcile elements and IDs of the project join point model (this) and
101
// a translation unit's join point
102
void reconcile (JoinPointModel &tunit_jpm);
104
// Result type for select ()
105
typedef JPLL Selection;
107
// constructor: initialize this model
108
JoinPointModel () : _root_namespace (0), _tunit_file (0) {}
110
// destructor: delete all stored join point locations
111
~JoinPointModel () { clear (); }
113
// get the root namespace
114
JPL_Namespace *root_namespace () const { return _root_namespace; }
116
// select and return all join points of a given type (any of them)
117
void select (JoinPointLoc::join_point_type jpt, Selection &result) {
118
for (JPLL::iterator iter = _elements.begin (); iter != _elements.end ();
120
JoinPointLoc::join_point_type curr_jpt = (*iter)->type ();
121
if ((curr_jpt & jpt) != 0) {
122
if (curr_jpt & (JoinPointLoc::Class | JoinPointLoc::Aspect)) {
123
JPL_Class *jpl = (JPL_Class*)*iter;
124
if (!jpl->intro_target ())
127
result.push_back (*iter);
132
// default registration of a new element
133
void register_elem (JoinPointLoc *jpl) {
134
register_entry (jpl);
137
// specialized version of element registration for name join-points
138
void register_elem (JPL_Name *jpl_name) {
139
register_name (jpl_name);
142
File *register_file (const string &name, int len, bool is_tunit) {
143
_files.push_back (File (name, len, is_tunit));
144
File *new_file = &_files.back ();
145
new_file->map (&_id_element_map);
146
new_file->id (_id_mgr.new_id ());
148
_tunit_file = new_file;
152
// functions that are needed to create the model elements
154
JPL_Namespace *new_namespace (JPL_Name *parent, const string &name) {
155
// check if this namespace is already known
157
JPL_Name *jpl = parent->lookup (name);
158
if (jpl && jpl->type () == JoinPointLoc::Namespace)
159
return (JPL_Namespace*)jpl; // it's known: return
162
if (root_namespace ())
163
return root_namespace ();
165
// create a new namespace and register
166
JPL_Namespace *new_elem = _factory.make_namespace (name);
167
register_elem (new_elem);
169
new_elem->parent (parent);
173
JPL_Function *new_function (JPL_Name *parent, const string &n, const string &s) {
174
// check if the function is already known
175
JPL_Name *jpl = parent->lookup (s);
176
if (jpl && (jpl->type () == JoinPointLoc::Function))
177
return (JPL_Function*)jpl;
178
// create a new function and register
179
JPL_Function *new_elem = _factory.make_function (n, s);
180
register_elem (new_elem);
181
new_elem->parent (parent);
185
JPL_AdviceCode *new_advice_code (JPL_Name *parent, const string &n, const string &s) {
186
// check if the advice code is already known
187
JPL_Name *jpl = parent->lookup (s);
188
if (jpl && (jpl->type () == JoinPointLoc::AdviceCode))
189
return (JPL_AdviceCode*)jpl;
190
// create a new advice code and register
191
JPL_AdviceCode *new_elem = _factory.make_advice_code (n, s);
192
register_elem (new_elem);
193
new_elem->parent (parent);
194
if (parent->type () == JoinPointLoc::Aspect) // TODO: use assert?
195
((JPL_Aspect*)parent)->advice_codes ().push_back (new_elem);
199
JPL_Class *new_class (JPL_Name *parent, const string &name) {
200
// check if the class is already known
201
JPL_Name *jpl = parent->lookup (name);
202
if (jpl && (jpl->type () == JoinPointLoc::Class))
203
return (JPL_Class*)jpl;
204
// create a new class and register
205
JPL_Class *new_elem = _factory.make_class (name);
206
register_elem (new_elem);
207
new_elem->parent (parent);
211
JPL_Aspect *new_aspect (JPL_Name *parent, const string &name) {
212
// check if the aspect is already known
213
JPL_Name *jpl = parent->lookup (name);
214
if (jpl && (jpl->type () == JoinPointLoc::Aspect))
215
return (JPL_Aspect*)jpl;
216
// create a new class ans register
217
JPL_Aspect *new_elem = _factory.make_aspect (name);
218
register_elem (new_elem);
219
new_elem->parent (parent);
223
JPL_ClassSlice *new_class_slice (JPL_Name *parent, const string &name) {
224
// check if this namespace is already known
225
JPL_Name *jpl = parent->lookup (name);
226
if (jpl && jpl->type () == JoinPointLoc::ClassSlice)
227
return (JPL_ClassSlice*)jpl; // it's known: return
228
// create a new namespace and register
229
JPL_ClassSlice *new_elem = _factory.make_class_slice (name);
230
register_elem (new_elem);
231
new_elem->parent (parent);
235
JPL_MethodCall *new_call (JPL_Function *target_func, int local_id) {
236
JPL_MethodCall *new_elem = _factory.make_call ();
237
new_elem->target_function (target_func);
238
new_elem->lid (local_id);
242
JPL_Method *new_execution (JPL_Function *f) {
243
JPL_Method *new_elem = _factory.make_execution ();
244
new_elem->parent (f);
248
JPL_Construction *new_construction (JPL_Function *f) {
249
JPL_Construction *new_elem = _factory.make_construction ();
250
new_elem->parent (f);
254
JPL_Destruction *new_destruction (JPL_Function *f) {
255
JPL_Destruction *new_elem = _factory.make_destruction ();
256
new_elem->parent (f);
260
JPL_Type *new_type (const string &name) {
261
return _factory.make_type (name);
264
// print the JoinPointModel
266
cout << "=======" << endl;
267
cout << "files:" << endl;
268
for (list<File>::const_iterator i = _files.begin (); i != _files.end (); ++i)
270
cout << "join points:" << endl;
271
if (root_namespace ())
272
root_namespace ()->dump ();
279
#endif // __join_point_model_h__