Skip to content

Commit 7a218f4

Browse files
committed
feat: Handlebars API
1 parent 21988cf commit 7a218f4

File tree

2 files changed

+342
-0
lines changed

2 files changed

+342
-0
lines changed

include/mrdox/Support/Handlebars.hpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//
2+
// This is a derivative work. originally part of the LLVM Project.
3+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
// Copyright (c) 2023 Vinnie Falco ([email protected])
8+
//
9+
// Official repository: https://github.com/cppalliance/mrdox
10+
//
11+
12+
#ifndef MRDOX_SUPPORT_HANDLEBARS_HPP
13+
#define MRDOX_SUPPORT_HANDLEBARS_HPP
14+
15+
#include <mrdox/Platform.hpp>
16+
#include <cstddef>
17+
#include <string_view>
18+
#include <system_error>
19+
20+
namespace clang {
21+
namespace mrdox {
22+
namespace hbs {
23+
24+
struct Access;
25+
class Object;
26+
27+
//------------------------------------------------
28+
29+
/** A reference to an instance of the Javascript interpreter.
30+
*/
31+
class Context
32+
{
33+
struct Impl;
34+
35+
Impl* impl_;
36+
37+
friend struct Access;
38+
39+
public:
40+
Context& operator=(Context const&) = delete;
41+
42+
MRDOX_DECL ~Context();
43+
MRDOX_DECL Context();
44+
MRDOX_DECL Context(Context const&) noexcept;
45+
46+
MRDOX_DECL std::error_code eval(std::string_view js);
47+
MRDOX_DECL std::error_code eval_file(std::string_view path);
48+
};
49+
50+
//------------------------------------------------
51+
52+
/** An ECMAScript Array.
53+
*/
54+
class Array
55+
{
56+
Context ctx_;
57+
int idx_;
58+
59+
friend struct Access;
60+
61+
public:
62+
Array(Array const&) = delete;
63+
Array& operator=(Array const&) = delete;
64+
65+
MRDOX_DECL ~Array();
66+
MRDOX_DECL Array(Context const& ctx);
67+
MRDOX_DECL void append(std::string_view value) const;
68+
MRDOX_DECL void append(Array const& value) const;
69+
MRDOX_DECL void append(Object const& value) const;
70+
};
71+
72+
//------------------------------------------------
73+
74+
/** An ECMAScript Object
75+
*/
76+
class Object
77+
{
78+
Context ctx_;
79+
int idx_;
80+
81+
friend struct Access;
82+
83+
public:
84+
Object(Object const&) = delete;
85+
Object& operator=(Object const&) = delete;
86+
87+
MRDOX_DECL ~Object();
88+
MRDOX_DECL Object(Context const& ctx);
89+
MRDOX_DECL void insert(std::string_view key, std::string_view value) const;
90+
MRDOX_DECL void insert(std::string_view key, Array const& value) const;
91+
MRDOX_DECL void insert(std::string_view key, Object const& value) const;
92+
};
93+
94+
//------------------------------------------------
95+
96+
/** A compiled Handlebars template.
97+
*/
98+
class Template
99+
{
100+
public:
101+
};
102+
103+
/** A compiled Handlebars partial.
104+
*/
105+
class Partial
106+
{
107+
public:
108+
};
109+
110+
//------------------------------------------------
111+
112+
/** An instance of the handlebars template engine.
113+
*/
114+
class Handlebars
115+
{
116+
Context ctx_;
117+
118+
public:
119+
explicit
120+
Handlebars(Context const& ctx) noexcept;
121+
122+
/** Return the loaded handlebars script.
123+
*/
124+
friend
125+
Handlebars
126+
loadHandlebarsScript(
127+
std::string_view path,
128+
std::error_code& ec);
129+
};
130+
131+
} // hbs
132+
} // mrdox
133+
} // clang
134+
135+
#endif

source/Support/Handlebars.cpp

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
//
2+
// This is a derivative work. originally part of the LLVM Project.
3+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
// Copyright (c) 2023 Vinnie Falco ([email protected])
8+
//
9+
// Official repository: https://github.com/cppalliance/mrdox
10+
//
11+
12+
#include <mrdox/Support/Handlebars.hpp>
13+
#include "duktape.h"
14+
#include <llvm/Support/MemoryBuffer.h>
15+
16+
namespace clang {
17+
namespace mrdox {
18+
namespace hbs {
19+
20+
//------------------------------------------------
21+
22+
// The current duk_context
23+
thread_local static ::duk_context* ctx_ = nullptr;
24+
25+
//------------------------------------------------
26+
27+
struct Context::Impl
28+
{
29+
std::size_t refs;
30+
::duk_context* ctx;
31+
32+
~Impl()
33+
{
34+
::duk_destroy_heap(ctx_);
35+
}
36+
37+
Impl()
38+
: refs(1)
39+
, ctx(::duk_create_heap_default())
40+
{
41+
}
42+
};
43+
44+
Context::
45+
~Context()
46+
{
47+
if(--impl_->refs == 0)
48+
delete impl_;
49+
}
50+
51+
Context::
52+
Context()
53+
: impl_(new Impl)
54+
{
55+
}
56+
57+
Context::
58+
Context(
59+
Context const& other) noexcept
60+
: impl_(other.impl_)
61+
{
62+
++impl_->refs;
63+
}
64+
65+
std::error_code
66+
Context::
67+
eval(
68+
std::string_view js)
69+
{
70+
// VFALCO How do we handle the error if any?
71+
duk_eval_lstring_noresult(impl_->ctx, js.data(), js.size());
72+
return {};
73+
}
74+
75+
std::error_code
76+
Context::
77+
eval_file(
78+
std::string_view path)
79+
{
80+
auto js = llvm::MemoryBuffer::getFile(path);
81+
if(! js)
82+
return js.getError();
83+
return eval(js->get()->getBuffer());
84+
}
85+
86+
//------------------------------------------------
87+
88+
struct Access
89+
{
90+
static int idx(Array const& arr) noexcept
91+
{
92+
return arr.idx_;
93+
}
94+
95+
static int idx(Object const& obj) noexcept
96+
{
97+
return obj.idx_;
98+
}
99+
100+
static ::duk_context* ctx(Context const& ctx) noexcept
101+
{
102+
return ctx.impl_->ctx;
103+
}
104+
};
105+
106+
//------------------------------------------------
107+
108+
Array::
109+
~Array()
110+
{
111+
if(idx_ != DUK_INVALID_INDEX)
112+
{
113+
// remove idx_ from stack?
114+
}
115+
}
116+
117+
Array::
118+
Array(
119+
Context const& ctx)
120+
: ctx_(ctx)
121+
, idx_(::duk_push_array(Access::ctx(ctx)))
122+
{
123+
}
124+
125+
void
126+
Array::
127+
append(
128+
std::string_view value) const
129+
{
130+
}
131+
132+
void
133+
Array::
134+
append(
135+
Array const& value) const
136+
{
137+
}
138+
139+
void
140+
Array::
141+
append(
142+
Object const& value) const
143+
{
144+
}
145+
146+
//------------------------------------------------
147+
148+
Object::
149+
~Object()
150+
{
151+
if(idx_ != DUK_INVALID_INDEX)
152+
{
153+
// remove idx_ from stack?
154+
}
155+
}
156+
157+
Object::
158+
Object(
159+
Context const& ctx)
160+
: ctx_(ctx)
161+
, idx_(::duk_push_object(Access::ctx(ctx)))
162+
{
163+
}
164+
165+
void
166+
Object::
167+
insert(
168+
std::string_view key,
169+
std::string_view value) const
170+
{
171+
::duk_push_lstring(Access::ctx(ctx_), value.data(), value.size());
172+
::duk_put_prop_lstring(Access::ctx(ctx_), idx_, key.data(), key.size());
173+
}
174+
175+
void
176+
Object::
177+
insert(
178+
std::string_view key,
179+
Array const& value) const
180+
{
181+
::duk_dup(Access::ctx(ctx_), Access::idx(value));
182+
::duk_put_prop_lstring(Access::ctx(ctx_), idx_, key.data(), key.size());
183+
}
184+
185+
void
186+
Object::
187+
insert(
188+
std::string_view key,
189+
Object const& value) const
190+
{
191+
::duk_dup(Access::ctx(ctx_), Access::idx(value));
192+
::duk_put_prop_lstring(Access::ctx(ctx_), idx_, key.data(), key.size());
193+
}
194+
195+
//------------------------------------------------
196+
197+
Handlebars::
198+
Handlebars(
199+
Context const& ctx) noexcept
200+
: ctx_(ctx)
201+
{
202+
203+
}
204+
205+
} // hbs
206+
} // mrdox
207+
} // clang

0 commit comments

Comments
 (0)