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
|
#pragma once
#include "repr.h"
#include "typeInfo.h"
#include <functional>
#include <optional>
template<typename T>
using opt = std::optional<T>;
template<typename T>
opt<T> find(const std::vector<T> & ts, std::function<bool(T)> f)
{
for (auto t : ts)
if (f(t))
return t;
return nullopt;
}
opt<Function> findFunction(
const Program & p,
const std::string & name,
const std::vector<std::string> & namespacePrefixes)
{
if (namespacePrefixes.empty())
{
return find<Function>(p.functions, [&](Function f) { return f.name == name; });
}
auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
if (!n.has_value())
return nullopt;
for (int i = 1; i < namespacePrefixes.size(); i++)
{
n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
if (!n.has_value())
return nullopt;
}
return find<Function>(n.value().functions, [&](Function f) { return f.name == name; });
}
opt<Struct> findStruct(
const Program & p,
const std::string & name,
const std::vector<std::string> & namespacePrefixes)
{
if (namespacePrefixes.empty())
{
return find<Struct>(p.structs, [&](Struct s) { return s.name == name; });
}
auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
if (!n.has_value())
return nullopt;
for (int i = 1; i < namespacePrefixes.size(); i++)
{
n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
if (!n.has_value())
return nullopt;
}
return find<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });
}
opt<Variable> findVariable(
const Program & p,
const std::string & name,
const std::vector<std::string> & namespacePrefixes)
{
for (auto n : namespacePrefixes)
std::cout << n << std::endl;
if (namespacePrefixes.empty())
{
return find<Variable>(p.variables, [&](Variable v) { return v.name == name; });
}
auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
if (!n.has_value())
return nullopt;
for (int i = 1; i < namespacePrefixes.size(); i++)
{
n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
if (!n.has_value())
return nullopt;
}
return find<Variable>(n.value().variables, [&](Variable v) { return v.name == name; });
}
opt<Function> findStructMethod(
const Program & p,
const std::string & name,
TypeInfo ti)
{
if (!ti.isStruct)
return nullopt;
auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);
if (!s.has_value())
return nullopt;
return find<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });
}
opt<Variable> findStructMember(
const Program & p,
TypeInfo ti,
const std::string & name)
{
auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);
if (!s.has_value())
return nullopt;
return find<StructMember<Variable>>(s.value().members, [&](Variable v) { return v.name == name; });
}
|