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__
27
#include "JoinPointLoc.h"
28
#include "TUnitModelElementFactory.h"
30
#include "RepoXMLNode.h"
31
#include "RepoIdMgr.h"
37
// This is just a simple container to manage the storage of join point
38
// location objects, which are used for scopes and world in the pointcut
41
class JoinPointModel {
42
IdElementMap _id_element_map;
43
typedef list<JoinPointLoc*> JPLL;
46
JPL_Namespace *_root_namespace;
49
TUnitModelElementFactory _factory;
51
void register_entry (JoinPointLoc *loc, bool new_id = true) {
52
_elements.push_back (loc);
53
loc->map (&_id_element_map);
55
loc->id (_id_mgr.new_id ());
58
_id_mgr.update (loc->id ());
61
void register_name (JPL_Name *jpl_name, bool new_id = true) {
62
register_entry (jpl_name, new_id);
63
if (jpl_name->is_root ()) _root_namespace = (JPL_Namespace*)jpl_name;
66
void unify (JoinPointLoc *tunit_loc);
68
void register_tree (JoinPointLoc *loc);
70
void reconcile (JPL_Name *tunit_name);
72
void reconcile_children (JPL_Name *tunit_name, JPL_Name *prj_name);
74
void copy_source_locs (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
76
bool equal_source_locs (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
78
void reconcile (JoinPointModelElement *tunit_elem,
79
JoinPointModelElement *prj_elem);
81
void reconcile (JoinPointLoc *tunit_loc, JoinPointLoc *prj_loc);
87
// file operation error codes
89
JPM_LOAD_ERR = -2, JPM_SAVE_ERR = -1, JPM_OK = 0 , JPM_VERSION = 1
92
// save the join point model in a file
93
FileOpResult save (int fd, const string &filename);
95
// discard the model and load new elements from a file
96
FileOpResult load (int fd, const string &filename);
98
// reconcile elements and IDs of the project join point model (this) and
99
// a translation unit's join point
100
void reconcile (JoinPointModel &tunit_jpm);
102
// Result type for select ()
103
typedef JPLL Selection;
105
// constructor: initialize this model
106
JoinPointModel () : _root_namespace (0), _tunit_file (0) {}
108
// destructor: delete all stored join point locations
109
~JoinPointModel () { clear (); }
111
// get the root namespace
112
JPL_Namespace *root_namespace () const { return _root_namespace; }
114
// select and return all join points of a given type (any of them)
115
void select (JoinPointLoc::join_point_type jpt, Selection &result) {
116
for (JPLL::iterator iter = _elements.begin (); iter != _elements.end ();
118
JoinPointLoc::join_point_type curr_jpt = (*iter)->type ();
119
if ((curr_jpt & jpt) != 0) {
120
if (curr_jpt & (JoinPointLoc::Class | JoinPointLoc::Aspect)) {
121
JPL_Class *jpl = (JPL_Class*)*iter;
122
if (!jpl->intro_target ())
125
result.push_back (*iter);
130
// default registration of a new element
131
void register_elem (JoinPointLoc *jpl) {
132
register_entry (jpl);
135
// specialized version of element registration for name join-points
136
void register_elem (JPL_Name *jpl_name) {
137
register_name (jpl_name);
140
File *register_file (const string &name, int len, bool is_tunit) {
141
_files.push_back (File (name, len, is_tunit));
142
File *new_file = &_files.back ();
143
new_file->map (&_id_element_map);
144
new_file->id (_id_mgr.new_id ());
146
_tunit_file = new_file;
150
// functions that are needed to create the model elements
152
JPL_Namespace *new_namespace (JPL_Name *parent, const string &name) {
153
// check if this namespace is already known
155
JPL_Name *jpl = parent->lookup (name);
156
if (jpl && jpl->type () == JoinPointLoc::Namespace)
157
return (JPL_Namespace*)jpl; // it's known: return
160
if (root_namespace ())
161
return root_namespace ();
163
// create a new namespace and register
164
JPL_Namespace *new_elem = _factory.make_namespace (name);
165
register_elem (new_elem);
167
new_elem->parent (parent);
171
JPL_Function *new_function (JPL_Name *parent, const string &n, const string &s) {
172
// check if the function is already known
173
JPL_Name *jpl = parent->lookup (s);
174
if (jpl && (jpl->type () == JoinPointLoc::Function))
175
return (JPL_Function*)jpl;
176
// create a new function and register
177
JPL_Function *new_elem = _factory.make_function (n, s);
178
register_elem (new_elem);
179
new_elem->parent (parent);
183
JPL_AdviceCode *new_advice_code (JPL_Name *parent, const string &n, const string &s) {
184
// check if the advice code is already known
185
JPL_Name *jpl = parent->lookup (s);
186
if (jpl && (jpl->type () == JoinPointLoc::AdviceCode))
187
return (JPL_AdviceCode*)jpl;
188
// create a new advice code and register
189
JPL_AdviceCode *new_elem = _factory.make_advice_code (n, s);
190
register_elem (new_elem);
191
new_elem->parent (parent);
192
if (parent->type () == JoinPointLoc::Aspect) // TODO: use assert?
193
((JPL_Aspect*)parent)->advice_codes ().push_back (new_elem);
197
JPL_Class *new_class (JPL_Name *parent, const string &name) {
198
// check if the class is already known
199
JPL_Name *jpl = parent->lookup (name);
200
if (jpl && (jpl->type () == JoinPointLoc::Class))
201
return (JPL_Class*)jpl;
202
// create a new class and register
203
JPL_Class *new_elem = _factory.make_class (name);
204
register_elem (new_elem);
205
new_elem->parent (parent);
209
JPL_Aspect *new_aspect (JPL_Name *parent, const string &name) {
210
// check if the aspect is already known
211
JPL_Name *jpl = parent->lookup (name);
212
if (jpl && (jpl->type () == JoinPointLoc::Aspect))
213
return (JPL_Aspect*)jpl;
214
// create a new class ans register
215
JPL_Aspect *new_elem = _factory.make_aspect (name);
216
register_elem (new_elem);
217
new_elem->parent (parent);
221
JPL_ClassSlice *new_class_slice (JPL_Name *parent, const string &name) {
222
// check if this namespace is already known
223
JPL_Name *jpl = parent->lookup (name);
224
if (jpl && jpl->type () == JoinPointLoc::ClassSlice)
225
return (JPL_ClassSlice*)jpl; // it's known: return
226
// create a new namespace and register
227
JPL_ClassSlice *new_elem = _factory.make_class_slice (name);
228
register_elem (new_elem);
229
new_elem->parent (parent);
233
JPL_MethodCall *new_call (JPL_Function *target_func, int local_id) {
234
JPL_MethodCall *new_elem = _factory.make_call ();
235
new_elem->target_function (target_func);
236
new_elem->lid (local_id);
240
JPL_Method *new_execution (JPL_Function *f) {
241
JPL_Method *new_elem = _factory.make_execution ();
242
new_elem->parent (f);
246
JPL_Construction *new_construction (JPL_Function *f) {
247
JPL_Construction *new_elem = _factory.make_construction ();
248
new_elem->parent (f);
252
JPL_Destruction *new_destruction (JPL_Function *f) {
253
JPL_Destruction *new_elem = _factory.make_destruction ();
254
new_elem->parent (f);
258
JPL_Type *new_type (const string &name) {
259
return _factory.make_type (name);
262
// print the JoinPointModel
264
cout << "=======" << endl;
265
cout << "files:" << endl;
266
for (list<File>::const_iterator i = _files.begin (); i != _files.end (); ++i)
268
cout << "join points:" << endl;
269
if (root_namespace ())
270
root_namespace ()->dump ();
275
#endif // __join_point_model_h__