forked from sorbet/sorbet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRails.cc
60 lines (55 loc) · 1.73 KB
/
Rails.cc
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
#include "rewriter/Rails.h"
#include "ast/Helpers.h"
#include "ast/ast.h"
#include "core/Context.h"
#include "core/Names.h"
#include "core/core.h"
#include "core/errors/rewriter.h"
#include "rewriter/rewriter.h"
using namespace std;
namespace sorbet::rewriter {
void Rails::run(core::MutableContext ctx, ast::ClassDef *cdef) {
if (cdef->ancestors.size() != 1) {
return;
}
auto send = ast::cast_tree<ast::Send>(cdef->ancestors[0]);
if (!send) {
return;
}
if (send->fun != core::Names::squareBrackets()) {
return;
}
auto name = ast::cast_tree<ast::UnresolvedConstantLit>(send->recv);
if (!name) {
return;
}
if (name->cnst != core::Names::Constants::Migration()) {
return;
}
auto name2 = ast::cast_tree<ast::UnresolvedConstantLit>(name->scope);
if (!name2) {
return;
}
if (name2->cnst != core::Names::Constants::ActiveRecord()) {
return;
}
if (send->numPosArgs() != 1 && !send->hasKwArgs()) {
return;
}
auto arg = ast::cast_tree<ast::Literal>(send->getPosArg(0));
if (!arg) {
return;
}
if (!core::isa_type<core::FloatLiteralType>(arg->value)) {
return;
}
auto &f = core::cast_type_nonnull<core::FloatLiteralType>(arg->value);
char version[5];
snprintf(version, sizeof(version), "V%.1f", f.value);
absl::c_replace(version, '.', '_');
cdef->ancestors.emplace_back(ast::MK::UnresolvedConstant(
arg->loc, ast::MK::UnresolvedConstant(arg->loc, std::move(send->recv), core::Names::Constants::Compatibility()),
ctx.state.enterNameConstant(version)));
cdef->ancestors.erase(cdef->ancestors.begin(), cdef->ancestors.begin() + 1);
}
}; // namespace sorbet::rewriter