abouttreesummaryrefslogcommitdiff
path: root/src/find.h
blob: 31400ab2b055132c8c4d57a3cae1d8eec1d1fa93 (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
#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; });
}