blob: 0abae105580826c689007a40edf6d1fccfeab39a (
plain)
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
|
/**
** \file object/renamer.cc
** \brief Implementation of object::Renamer.
*/
#include <memory>
#include <object/renamer.hh>
namespace object
{
using namespace ast;
Renamer::Renamer()
: super_type()
, class_names_(new class_names_type)
, within_class_ty_(false)
{
// Give a name to the built-in class Object.
misc::put(*class_names_, &type::Class::object_instance(), "Object");
}
/**
* Get the node's type as a class, if it references one
* @param ast Any typable node
* @return The node's referenced class type if there is one, nullptr if not
*/
static inline const type::Class* get_referenced_class_type(const Typable& ast)
{
return dynamic_cast<const type::Class*>(&ast.type_get()->actual());
}
/*----------------------------.
| Visiting definition sites. |
`----------------------------*/
void Renamer::operator()(ast::VarDec& e)
{
if (within_class_ty_)
// Don't rename class attributes.
super_type::super_type::operator()(e);
else
// But still rename other variable declarations.
super_type::operator()(e);
}
void Renamer::operator()(ast::MethodChunk& e)
{
// FIXME DONE: Some code was deleted here (Just recurse on children nodes).
chunk_visit<MethodChunk>(e);
}
void Renamer::operator()(ast::MethodDec& e)
{
bool saved_within_class_ty = within_class_ty_;
within_class_ty_ = false;
/* We can't call bind::Binder::visit directly, because this method
delegates the recursion task to DefaultVisitor, which doesn't
have a proper operator() for MethodDec. This visitor however
knows how to handle a FunctionDec; therefore we upcast the
MethodDec to a FunctionDec before visiting it. */
ast::FunctionDec& fundec = e;
visit(fundec, &fundec);
within_class_ty_ = saved_within_class_ty;
}
void Renamer::operator()(ast::TypeDec& e)
{
// Rename.
// FIXME DONE: Some code was deleted here.
if (class_names_->find(get_referenced_class_type(e)) == class_names_->end())
super_type::operator()(e);
// Collect the name of the classes.
// FIXME DONE: Some code was deleted here.
if (auto classtype = get_referenced_class_type(e))
{
class_names_->insert(std::make_pair(classtype, e.name_get()));
}
}
/*-----------------------.
| Visiting usage sites. |
`-----------------------*/
void Renamer::operator()(ast::MethodCallExp& e)
{
// FIXME DONE: Some code was deleted here.
super_type::operator()(e.object_get());
e.name_set(e.def_get()->name_get());
CallExp& upcast = e;
precondition(upcast.def_get() == nullptr);
super_type::operator()(upcast);
}
/*--------------------------------------.
| Visiting other object-related nodes. |
`--------------------------------------*/
void Renamer::operator()(ast::ClassTy& e)
{
// FIXME DONE: Some code was deleted here.
bool saved_within_class_ty = within_class_ty_;
within_class_ty_ = true;
if (e.super_get().name_get() != "Object")
e.super_get().name_set(e.super_get().def_get()->name_get());
super_type::operator()(e.chunks_get());
within_class_ty_ = saved_within_class_ty;
}
void Renamer::operator()(ast::ObjectExp& e)
{
// FIXME DONE: Some code was deleted here.
if (auto name = class_names_->find(get_referenced_class_type(e));
name != class_names_->end())
e.type_name_get().name_set(name->second);
else
{
this->accept(e.type_name_get().def_get());
e.type_name_get().name_set(e.type_name_get().def_get()->name_get());
class_names_->insert(
std::make_pair(get_referenced_class_type(e),
e.type_name_get().name_get()));
}
}
void Renamer::operator()(ast::LetExp& e)
{
// FIXME DONE: Some code was deleted here.
bool saved_within_class_ty = within_class_ty_;
within_class_ty_ = false;
super_type::operator()(e);
within_class_ty_ = saved_within_class_ty;
}
/*--------------.
| Class names. |
`--------------*/
class_names_type* Renamer::class_names_get() const { return class_names_; }
} // namespace object
|