Joos1W Compiler Framework
All Classes Functions Typedefs Pages
DeclContext.h
1 #pragma once
2 
3 #include <ranges>
4 
5 #include "ast/AstNode.h"
6 #include "ast/Decl.h"
7 #include "ast/Type.h"
8 #include "utils/Generator.h"
9 #include "utils/Utils.h"
10 
11 namespace ast {
12 
13 class VarDecl;
14 class FieldDecl;
15 class MethodDecl;
16 
18  ReferenceType* type;
19  bool isOnDemand;
20  std::string_view simpleName() const {
21  // Can only extract simple name from unresolved type
22  auto unresTy = cast<UnresolvedType*>(type);
23  return unresTy->parts().back();
24  }
25  SourceRange location() const { return type->location(); }
26 };
27 
28 class CompilationUnit final : public DeclContext {
29 public:
30  CompilationUnit(BumpAllocator& alloc, ReferenceType* package,
31  array_ref<ImportDeclaration> imports, SourceRange location,
32  DeclContext* body) noexcept;
33  auto const* body() const { return body_; }
34  auto const* bodyAsDecl() const { return dyn_cast_or_null<Decl>(body_); }
35  auto mut_bodyAsDecl() { return dyn_cast_or_null<Decl>(body_); }
36  std::ostream& print(std::ostream& os, int indentation = 0) const override;
37  int printDotNode(DotPrinter& dp) const override;
38  string_view getPackageName() const {
39  assert(package_ && "Package can never be null");
40  // Package must be unresolved type
41  auto package = cast<UnresolvedType*>(package_);
42  if(package->parts().size() > 0) return package_->toString();
43  return "";
44  }
45  SourceRange location() const { return location_; }
46  auto const* package() const { return package_; }
47  auto imports() const { return std::views::all(imports_); }
48  auto isDefaultPackage() const {
49  if(!package_) return true;
50  // Package must be unresolved type
51  auto unresTy = cast<UnresolvedType*>(package_);
52  return unresTy->parts().size() == 0;
53  }
54  utils::Generator<ast::AstNode const*> children() const override {
55  co_yield package_;
56  for(auto import : imports_) co_yield import.type;
57  co_yield body_;
58  }
59  auto mut_body() { return body_; }
60  bool isStdLib() const {
61  // Package must be unresolved type
62  auto package = cast<UnresolvedType*>(package_);
63  return package->parts().size() >= 1 && package->parts().front() == "java";
64  }
65 
66 private:
67  ReferenceType* package_;
68  pmr_vector<ImportDeclaration> imports_;
69  DeclContext* body_;
70  SourceRange location_;
71 };
72 
73 class LinkingUnit final : public DeclContext {
74 public:
75  LinkingUnit(BumpAllocator& alloc,
76  array_ref<CompilationUnit*> compilationUnits) noexcept;
77  auto compliationUnits() const { return std::views::all(compilationUnits_); }
78  std::ostream& print(std::ostream& os, int indentation = 0) const override;
79  int printDotNode(DotPrinter& dp) const override;
80  utils::Generator<ast::AstNode const*> children() const override {
81  for(auto cu : compilationUnits_) co_yield cu;
82  }
83 
84 private:
85  pmr_vector<CompilationUnit*> compilationUnits_;
86 };
87 
88 class ClassDecl final : public DeclContext, public Decl {
89 public:
90  ClassDecl(BumpAllocator& alloc, Modifiers modifiers, SourceRange location,
91  string_view name, ReferenceType* super1, ReferenceType* super2,
92  array_ref<ReferenceType*> interfaces,
93  array_ref<Decl*> classBodyDecls) throw();
94  auto fields() const { return std::views::all(fields_); }
95  auto methods() const { return std::views::all(methods_); }
96  auto constructors() const { return std::views::all(constructors_); }
97  auto interfaces() const { return std::views::all(interfaces_); }
98  /// @brief Grabs a view of the super classes.
99  /// Warning: the super classes may be null.
100  auto superClasses() const { return std::views::all(superClasses_); }
101  auto& mut_superClasses() { return superClasses_; }
102  auto modifiers() const { return modifiers_; }
103  bool hasCanonicalName() const override { return true; }
104  std::ostream& print(std::ostream& os, int indentation = 0) const override;
105  int printDotNode(DotPrinter& dp) const override;
106  /// @brief Overrides the setParent to construct canonical name.
107  void setParent(DeclContext* parent) override;
108  SourceRange location() const override { return location_; }
109  DeclContext const* asDeclContext() const override { return this; }
110  Decl const* asDecl() const override { return this; }
111  utils::Generator<ast::AstNode const*> children() const override {
112  for(auto field : fields_) co_yield field;
113  for(auto method : methods_) co_yield reinterpret_cast<Decl*>(method);
114  for(auto constructor : constructors_)
115  co_yield reinterpret_cast<Decl*>(constructor);
116  for(auto interface : interfaces_) co_yield interface;
117  for(auto superClass : superClasses_) co_yield superClass;
118  }
119  bool hasDefaultCtor() const;
120 
121 private:
122  Modifiers modifiers_;
123  std::array<ReferenceType*, 2> superClasses_;
124  pmr_vector<ReferenceType*> interfaces_;
125  pmr_vector<FieldDecl*> fields_;
126  pmr_vector<MethodDecl*> methods_;
127  pmr_vector<MethodDecl*> constructors_;
128  SourceRange location_;
129 };
130 
131 class InterfaceDecl final : public DeclContext, public Decl {
132 public:
133  InterfaceDecl(BumpAllocator& alloc, Modifiers modifiers, SourceRange location,
134  string_view name, array_ref<ReferenceType*> extends,
135  ReferenceType* objectSuperclass,
136  array_ref<Decl*> interfaceBodyDecls) throw();
137  auto extends() const { return std::views::all(extends_); }
138  auto methods() const { return std::views::all(methods_); }
139  auto modifiers() const { return modifiers_; }
140  auto const* objectSuperclass() const { return objectSuperclass_; }
141  bool hasCanonicalName() const override { return true; }
142  std::ostream& print(std::ostream& os, int indentation = 0) const override;
143  int printDotNode(DotPrinter& dp) const override;
144  /// @brief Overrides the setParent to construct canonical name.
145  void setParent(DeclContext* parent) override;
146  SourceRange location() const override { return location_; }
147  DeclContext const* asDeclContext() const override { return this; }
148  Decl const* asDecl() const override { return this; }
149  utils::Generator<ast::AstNode const*> children() const override {
150  for(auto method : methods_) co_yield reinterpret_cast<Decl*>(method);
151  for(auto superClass : extends_) co_yield superClass;
152  }
153 
154 private:
155  Modifiers modifiers_;
156  pmr_vector<ReferenceType*> extends_;
157  pmr_vector<MethodDecl*> methods_;
158  SourceRange location_;
159  ReferenceType* objectSuperclass_;
160 };
161 
162 class MethodDecl final : public virtual DeclContext, public virtual Decl {
163 public:
164  MethodDecl(BumpAllocator& alloc, Modifiers modifiers, SourceRange location,
165  string_view name, Type* returnType, array_ref<VarDecl*> parameters,
166  bool isConstructor, Stmt* body) noexcept
167  : Decl{alloc, name},
168  modifiers_{modifiers},
169  returnType_{returnType},
170  parameters_{alloc},
171  locals_{alloc},
172  isConstructor_{isConstructor},
173  body_{body},
174  location_{location} {
175  utils::move_vector<VarDecl*>(parameters, parameters_);
176  }
177  auto modifiers() const { return modifiers_; }
178  bool isConstructor() const { return isConstructor_; }
179  auto parameters() const { return std::views::all(parameters_); }
180  bool hasCanonicalName() const override { return true; }
181  std::ostream& print(std::ostream& os, int indentation = 0) const override;
182  int printDotNode(DotPrinter& dp) const override;
183  /// @brief Overrides the setParent to construct canonical name.
184  void setParent(DeclContext* parent) override;
185  template <std::ranges::range T>
186  requires std::same_as<std::ranges::range_value_t<T>, VarDecl*>
187  void addDecls(T decls) {
188  locals_.reserve(decls.size());
189  locals_.insert(locals_.end(), decls.begin(), decls.end());
190  }
191  SourceRange location() const override { return location_; }
192  ReturnType returnTy() const { return ReturnType{returnType_}; }
193  DeclContext const* asDeclContext() const override { return this; }
194  Decl const* asDecl() const override { return this; }
195  Stmt const* body() const { return body_; }
196 
197  utils::Generator<ast::AstNode const*> children() const override {
198  co_yield returnType_;
199  for(auto local : locals_) co_yield local;
200  co_yield body_;
201  }
202  std::ostream& printSignature(std::ostream& os) const;
203  void dumpSignature() const;
204 
205 private:
206  Modifiers modifiers_;
207  Type* returnType_;
208  pmr_vector<VarDecl*> parameters_;
209  pmr_vector<VarDecl*> locals_;
210  bool isConstructor_;
211  Stmt* body_;
212  SourceRange location_;
213 };
214 
215 } // namespace ast