LLVM: lib/Support/Mustache.cpp Source File (original) (raw)
1
2
3
4
5
6
7
12#include
13#include
14
15#define DEBUG_TYPE "mustache"
16
17using namespace llvm;
19
20namespace {
21
23
24static bool isFalsey(const json::Value &V) {
25 return V.getAsNull() || (V.getAsBoolean() && !V.getAsBoolean().value()) ||
26 (V.getAsArray() && V.getAsArray()->empty());
27}
28
29static bool isContextFalsey(const json::Value *V) {
30
31 if (!V)
32 return true;
33 return isFalsey(*V);
34}
35
37 size_t CurrentPos = 0;
38 while (CurrentPos < Str.size()) {
39
40 size_t DelimiterPos = Str.find('.', CurrentPos);
41
42
44 DelimiterPos = Str.size();
45
46
48
49
54 }
55
56
57 CurrentPos = DelimiterPos + 1;
58 }
59}
60
62
63
64
65
66
68 if (Str == ".") {
69
70
72 } else {
73 splitAndTrim(Str, Tokens);
74 }
75
77
79
81}
82}
83
85
87public:
90
93
94private:
95 void anchor() override;
96};
97
98void MustacheOutputStream::anchor() {}
99
101public:
103
104private:
106
107 void write_impl(const char *Ptr, size_t Size) override {
109 }
110 uint64_t current_pos() const override { return OS.tell(); }
111};
112
114public:
126
130
136 return;
137 StringRef AccessorStr(this->TokenBody);
139 AccessorStr = AccessorStr.substr(1);
141 }
142
144
146
148
150
152 switch (Identifier) {
153 case '#':
155 case '/':
157 case '^':
159 case '!':
161 case '>':
163 case '&':
165 case '=':
167 default:
169 }
170 }
171
173
175
179};
180
182
184public:
194
196 : Ctx(Ctx), Ty(Type::Root), Parent(nullptr), ParentContext(nullptr) {}
197
199 : Ctx(Ctx), Ty(Type::Text), Body(Body), Parent(Parent),
200 ParentContext(nullptr) {}
201
202
205 : Ctx(Ctx), Ty(Ty), Parent(Parent), AccessorValue(Accessor),
206 ParentContext(nullptr) {}
207
209
211
212 void setIndentation(size_t NewIndentation) { Indentation = NewIndentation; };
213
215
216private:
219
222
225
227
229
234 void renderUnescapeVariable(const json::Value &CurrentCtx,
237 void renderInvertSection(const json::Value &CurrentCtx,
239
242 size_t Indentation = 0;
249};
250
251
255
258 return new (Ctx.Allocator.Allocate<ASTNode>()) ASTNode(Ctx, T, A, Parent);
259}
260
263 return new (Ctx.Allocator.Allocate<ASTNode>()) ASTNode(Ctx, Body, Parent);
264}
265
266
267
268
269
270
271
272
273
274
275
276
277
279 if (Idx == 0)
280 return true;
281
282 size_t PrevIdx = Idx - 1;
284 return true;
285
286 const Token &PrevToken = Tokens[PrevIdx];
288 return !TokenBody.ends_with("\n") && !(TokenBody.empty() && Idx == 1);
289}
290
291
292
293
295 if (Idx >= Tokens.size() - 1)
296 return true;
297
298 size_t NextIdx = Idx + 1;
300 return true;
301
302 const Token &NextToken = Tokens[NextIdx];
305}
306
313
314
315
316
317
318
319
321 Token &NextToken = Tokens[Idx + 1];
323
326 else if (NextTokenBody.starts_with("\n"))
328}
329
330
331
332
333
334
335
338 Token &PrevToken = Tokens[Idx - 1];
340 StringRef Unindented = PrevTokenBody.rtrim(" \r\t\v");
341 size_t Indentation = PrevTokenBody.size() - Unindented.size();
342 PrevToken.TokenBody = Unindented;
344}
345
358
360 switch (K) {
362 return "None";
364 return "Normal";
366 return "Triple";
367 }
369}
370
372 switch (K) {
374 return "JSON_KIND_NULL";
376 return "JSON_KIND_BOOLEAN";
378 return "JSON_KIND_NUMBER";
380 return "JSON_KIND_STRING";
382 return "JSON_KIND_ARRAY";
384 return "JSON_KIND_OBJECT";
385 }
387}
388
389
395 size_t Cursor = 0;
396 size_t TextStart = 0;
397
400
401 while (Cursor < Template.size()) {
405
406
407 if (TemplateSuffix.starts_with(TripleOpen)) {
409 TagOpen = TripleOpen;
410 TagClose = TripleClose;
411 } else if (TemplateSuffix.starts_with(Open)) {
413 TagOpen = Open;
414 TagClose = Close;
415 } else {
416
417 ++Cursor;
418 continue;
419 }
420
421
422 if (Cursor > TextStart)
424
425
426 size_t EndPos = Template.find(TagClose, Cursor + TagOpen.size());
428
430 TextStart = Cursor = Template.size();
431 break;
432 }
433
434
435 size_t ContentStart = Cursor + TagOpen.size();
436 StringRef Content = Template.substr(ContentStart, EndPos - ContentStart);
438 Template.substr(Cursor, (EndPos + TagClose.size()) - Cursor);
439
440
441 LLVM_DEBUG(dbgs() << "[Tag] " << FullMatch << ", Content: " << Content
444 Tokens.emplace_back(FullMatch, Ctx.Saver.save("&" + Content), '&', Ctx);
445 } else {
446 StringRef Interpolated = Content;
448 char Front = Interpolated.empty() ? ' ' : Interpolated.trim().front();
449 Tokens.emplace_back(FullMatch, Interpolated, Front, Ctx);
450 } else {
451 Tokens.emplace_back(FullMatch, Interpolated, '=', Ctx);
454 DelimSpec = DelimSpec.take_until([](char C) { return C == '='; });
455 DelimSpec = DelimSpec.trim();
456
457 auto [NewOpen, NewClose] = DelimSpec.split(' ');
458 LLVM_DEBUG(dbgs() << "[Set Delimiter] NewOpen: " << NewOpen
459 << ", NewClose: " << NewClose << "\n");
460 Open = NewOpen;
461 Close = NewClose;
462 }
463 }
464
465
466 Cursor += FullMatch.size();
467 TextStart = Cursor;
468 }
469
470
471 if (TextStart < Template.size())
473
474
475 size_t LastIdx = Tokens.size() - 1;
476 for (size_t Idx = 0, End = Tokens.size(); Idx < End; ++Idx) {
477 Token &CurrentToken = Tokens[Idx];
480 continue;
481
483 bool HasTextAhead = hasTextAhead(Idx, Tokens);
484
485 if ((!HasTextAhead && !HasTextBehind) || (!HasTextAhead && Idx == 0))
487
488 if ((!HasTextBehind && !HasTextAhead) || (!HasTextBehind && Idx == LastIdx))
490 }
491 return Tokens;
492}
493
494
496public:
499 : Escape(Escape), EscapeChars(Escape.keys().begin(), Escape.keys().end()),
500 WrappedStream(WrappedStream) {
502 }
503
504protected:
507 size_t Start = 0;
508 while (Start < Size) {
509
510 size_t Next = Data.find_first_of(EscapeChars.str(), Start);
511
512
514 WrappedStream << Data.substr(Start);
515 return;
516 }
517
518
519 if (Next > Start)
520 WrappedStream << Data.substr(Start, Next - Start);
521
522
523 WrappedStream << Escape[Data[Next]];
524 Start = Next + 1;
525 }
526 }
527
529
530private:
534};
535
536
538public:
540 size_t Indentation)
541 : Indentation(Indentation), WrappedStream(WrappedStream),
542 NeedsIndent(true), IsSuspended(false) {
544 }
545
548
549protected:
553 Indent.resize(Indentation, ' ');
554
556 LLVM_DEBUG(dbgs() << "[Indentation Stream] NeedsIndent:" << NeedsIndent
557 << ", C:'" << C << "', Indentation:" << Indentation
558 << "\n");
559 if (NeedsIndent && C != '\n') {
560 WrappedStream << Indent;
561 NeedsIndent = false;
562 }
563 WrappedStream << C;
564 if (C == '\n' && !IsSuspended)
565 NeedsIndent = true;
566 }
567 }
568
570
571private:
572 size_t Indentation;
574 bool NeedsIndent;
575 bool IsSuspended;
576};
577
579public:
581 : Ctx(Ctx), TemplateStr(TemplateStr) {}
582
584
585private:
586 void parseMustache(ASTNode *Parent);
588
591 size_t CurrentPtr;
593};
594
596 const Accessor &A) {
598 size_t Start = CurrentPtr;
599 parseMustache(CurrentNode);
600 const size_t End = CurrentPtr - 1;
601
602 size_t RawBodySize = 0;
603 for (size_t I = Start; I < End; ++I)
604 RawBodySize += Tokens[I].RawBody.size();
605
607 RawBody.reserve(RawBodySize);
608 for (std::size_t I = Start; I < End; ++I)
609 RawBody += Tokens[I].RawBody;
610
612 Parent->addChild(CurrentNode);
613}
614
616 Tokens = tokenize(TemplateStr, Ctx);
617 CurrentPtr = 0;
619 parseMustache(RootNode);
620 return RootNode;
621}
622
623void Parser::parseMustache(ASTNode *Parent) {
624
625 while (CurrentPtr < Tokens.size()) {
626 Token CurrentToken = Tokens[CurrentPtr];
627 CurrentPtr++;
630
631 switch (CurrentToken.getType()) {
634 Parent->addChild(CurrentNode);
635 break;
636 }
639 Parent->addChild(CurrentNode);
640 break;
641 }
644 Parent->addChild(CurrentNode);
645 break;
646 }
650 Parent->addChild(CurrentNode);
651 break;
652 }
655 break;
656 }
659 break;
660 }
663 break;
665 return;
666 }
667 }
668}
672 << "\n");
673 switch (Data.kind()) {
675 return;
677 auto Num = *Data.getAsNumber();
678 std::ostringstream SS;
679 SS << Num;
680 OS << SS.str();
681 return;
682 }
684 OS << *Data.getAsString();
685 return;
686 }
687
689 auto Arr = *Data.getAsArray();
690 if (Arr.empty())
691 return;
692 [[fallthrough]];
693 }
698 break;
699 }
700 }
701}
702
703void ASTNode::renderRoot(const json::Value &CurrentCtx,
705 renderChild(CurrentCtx, OS);
706}
707
709
710void ASTNode::renderPartial(const json::Value &CurrentCtx,
712 LLVM_DEBUG(dbgs() << "[Render Partial] Accessor:" << AccessorValue[0]
713 << ", Indentation:" << Indentation << "\n");
714 auto Partial = Ctx.Partials.find(AccessorValue[0]);
715 if (Partial != Ctx.Partials.end())
716 renderPartial(CurrentCtx, OS, Partial->getValue());
717}
718
719void ASTNode::renderVariable(const json::Value &CurrentCtx,
721 auto Lambda = Ctx.Lambdas.find(AccessorValue[0]);
722 if (Lambda != Ctx.Lambdas.end()) {
723 renderLambdas(CurrentCtx, OS, Lambda->getValue());
724 } else if (const json::Value *ContextPtr = findContext()) {
725 EscapeStringStream ES(OS, Ctx.Escapes);
727 }
728}
729
730void ASTNode::renderUnescapeVariable(const json::Value &CurrentCtx,
732 LLVM_DEBUG(dbgs() << "[Render UnescapeVariable] Accessor:" << AccessorValue[0]
733 << "\n");
734 auto Lambda = Ctx.Lambdas.find(AccessorValue[0]);
735 if (Lambda != Ctx.Lambdas.end()) {
736 renderLambdas(CurrentCtx, OS, Lambda->getValue());
737 } else if (const json::Value *ContextPtr = findContext()) {
741 }
742}
743
744void ASTNode::renderSection(const json::Value &CurrentCtx,
746 auto SectionLambda = Ctx.SectionLambdas.find(AccessorValue[0]);
748 renderSectionLambdas(CurrentCtx, OS, SectionLambda->getValue());
749 return;
750 }
751
752 const json::Value *ContextPtr = findContext();
753 if (isContextFalsey(ContextPtr))
754 return;
755
756 if (const json::Array *Arr = ContextPtr->getAsArray()) {
757 for (const json::Value &V : *Arr)
758 renderChild(V, OS);
759 return;
760 }
761 renderChild(*ContextPtr, OS);
762}
763
764void ASTNode::renderInvertSection(const json::Value &CurrentCtx,
766 bool IsLambda = Ctx.SectionLambdas.contains(AccessorValue[0]);
767 const json::Value *ContextPtr = findContext();
768 if (isContextFalsey(ContextPtr) && !IsLambda) {
769 renderChild(CurrentCtx, OS);
770 }
771}
772
774 if (Ty != Root && Ty != Text && AccessorValue.empty())
775 return;
776
777
778 ParentContext = &Data;
779
780 switch (Ty) {
782 renderRoot(Data, OS);
783 return;
785 renderText(OS);
786 return;
788 renderPartial(Data, OS);
789 return;
791 renderVariable(Data, OS);
792 return;
794 renderUnescapeVariable(Data, OS);
795 return;
797 renderSection(Data, OS);
798 return;
800 renderInvertSection(Data, OS);
801 return;
802 }
804}
805
806const json::Value *ASTNode::findContext() {
807
808
809
810
811
812 if (AccessorValue.empty())
813 return nullptr;
814 if (AccessorValue[0] == ".")
815 return ParentContext;
816
818 StringRef CurrentAccessor = AccessorValue[0];
819 ASTNode *CurrentParent = Parent;
820
821 while (!CurrentContext || !CurrentContext->get(CurrentAccessor)) {
822 if (CurrentParent->Ty != Root) {
823 CurrentContext = CurrentParent->ParentContext->getAsObject();
824 CurrentParent = CurrentParent->Parent;
825 continue;
826 }
827 return nullptr;
828 }
830 for (auto [Idx, Acc] : enumerate(AccessorValue)) {
831 const json::Value *CurrentValue = CurrentContext->get(Acc);
832 if (!CurrentValue)
833 return nullptr;
834 if (Idx < AccessorValue.size() - 1) {
835 CurrentContext = CurrentValue->getAsObject();
836 if (!CurrentContext)
837 return nullptr;
838 } else {
840 }
841 }
843}
844
845void ASTNode::renderChild(const json::Value &Contexts,
847 for (ASTNode &Child : Children)
848 Child.render(Contexts, OS);
849}
850
851void ASTNode::renderPartial(const json::Value &Contexts,
853 LLVM_DEBUG(dbgs() << "[Render Partial Indentation] Indentation: " << Indentation << "\n");
854 AddIndentationStringStream IS(OS, Indentation);
855 Partial->render(Contexts, IS);
856}
857
858void ASTNode::renderLambdas(const llvm::json::Value &Contexts,
860 json::Value LambdaResult = L();
861 std::string LambdaStr;
862 raw_string_ostream Output(LambdaStr);
864 Parser P(LambdaStr, Ctx);
865 AstPtr LambdaNode = P.parse();
866
867 EscapeStringStream ES(OS, Ctx.Escapes);
869 LambdaNode->render(Contexts, ES);
870 return;
871 }
872 LambdaNode->render(Contexts, OS);
873}
874
875void ASTNode::renderSectionLambdas(const llvm::json::Value &Contexts,
877 json::Value Return = L(RawBody.str());
878 if (isFalsey(Return))
879 return;
880 std::string LambdaStr;
881 raw_string_ostream Output(LambdaStr);
883 Parser P(LambdaStr, Ctx);
884 AstPtr LambdaNode = P.parse();
885 LambdaNode->render(Contexts, OS);
886}
887
890 Tree->render(Data, MOS);
891}
892
894 StringRef SavedPartial = Ctx.Saver.save(Partial);
895 Parser P(SavedPartial, Ctx);
896 AstPtr PartialTree = P.parse();
897 Ctx.Partials.insert(std::make_pair(Name, PartialTree));
898}
899
901 Ctx.Lambdas[Name] = L;
902}
903
905 Ctx.SectionLambdas[Name] = L;
906}
907
909 Ctx.Escapes = std::move(E);
910}
911
913 Parser P(TemplateStr, Ctx);
914 Tree = P.parse();
915
916 const EscapeMap HtmlEntities = {{'&', "&"},
917 {'<', "<"},
918 {'>', ">"},
919 {'"', """},
920 {'\'', "'"}};
922}
923
926 Other.Tree = nullptr;
927}
928
930
931}
932
933#undef DEBUG_TYPE
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
LLVM_ABI size_t find_last_not_of(char C, size_t From=npos) const
Find the last character in the string that is not C, or npos if not found.
static constexpr size_t npos
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
StringRef take_until(function_ref< bool(char)> F) const
Return the longest prefix of 'this' such that no character in the prefix satisfies the given predicat...
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
LLVM_ABI size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
The instances of the Type class are immutable: once they are created, they are never changed.
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
LLVM_ABI void value(const Value &V)
Emit a self-contained value (number, string, vector etc).
An Object is a JSON object, which maps strings to heterogenous JSON values.
LLVM_ABI Value * get(StringRef K)
A Value is an JSON value of unknown type.
@ Number
Number values can store both int64s and doubles at full precision, depending on what they were constr...
const json::Object * getAsObject() const
const json::Array * getAsArray() const
Definition Mustache.cpp:183
ASTNode(MustacheContext &Ctx, Type Ty, ArrayRef< StringRef > Accessor, ASTNode *Parent)
Definition Mustache.cpp:203
ASTNode(MustacheContext &Ctx)
Definition Mustache.cpp:195
Type
Definition Mustache.cpp:185
@ Variable
Definition Mustache.cpp:189
@ Section
Definition Mustache.cpp:191
@ Root
Definition Mustache.cpp:186
@ InvertSection
Definition Mustache.cpp:192
@ Partial
Definition Mustache.cpp:188
@ Text
Definition Mustache.cpp:187
@ UnescapeVariable
Definition Mustache.cpp:190
void setIndentation(size_t NewIndentation)
Definition Mustache.cpp:212
ASTNode(MustacheContext &Ctx, StringRef Body, ASTNode *Parent)
Definition Mustache.cpp:198
void setRawBody(StringRef NewBody)
Definition Mustache.cpp:210
void render(const llvm::json::Value &Data, MustacheOutputStream &OS)
Definition Mustache.cpp:773
void addChild(AstPtr Child)
Definition Mustache.cpp:208
void resumeIndentation() override
Definition Mustache.cpp:547
AddIndentationStringStream(raw_ostream &WrappedStream, size_t Indentation)
Definition Mustache.cpp:539
uint64_t current_pos() const override
Return the current position within the stream, not counting the bytes currently in the buffer.
Definition Mustache.cpp:569
void write_impl(const char *Ptr, size_t Size) override
The is the piece of the class that is implemented by subclasses.
Definition Mustache.cpp:550
void suspendIndentation() override
Definition Mustache.cpp:546
uint64_t current_pos() const override
Return the current position within the stream, not counting the bytes currently in the buffer.
Definition Mustache.cpp:528
void write_impl(const char *Ptr, size_t Size) override
The is the piece of the class that is implemented by subclasses.
Definition Mustache.cpp:505
EscapeStringStream(llvm::raw_ostream &WrappedStream, EscapeMap &Escape)
Definition Mustache.cpp:497
Definition Mustache.cpp:86
MustacheOutputStream()=default
virtual void suspendIndentation()
Definition Mustache.cpp:91
~MustacheOutputStream() override=default
virtual void resumeIndentation()
Definition Mustache.cpp:92
Definition Mustache.cpp:578
Parser(StringRef TemplateStr, MustacheContext &Ctx)
Definition Mustache.cpp:580
AstPtr parse()
Definition Mustache.cpp:615
Definition Mustache.cpp:100
RawMustacheOutputStream(raw_ostream &OS)
Definition Mustache.cpp:102
LLVM_ABI void registerPartial(std::string Name, std::string Partial)
Definition Mustache.cpp:893
LLVM_ABI void registerLambda(std::string Name, Lambda Lambda)
Definition Mustache.cpp:900
LLVM_ABI Template(StringRef TemplateStr, MustacheContext &Ctx)
Definition Mustache.cpp:912
LLVM_ABI void render(const llvm::json::Value &Data, llvm::raw_ostream &OS)
Definition Mustache.cpp:888
LLVM_ABI void overrideEscapeCharacters(DenseMap< char, std::string > Escapes)
Definition Mustache.cpp:908
Definition Mustache.cpp:113
Type getType() const
Definition Mustache.cpp:145
size_t getIndentation() const
Definition Mustache.cpp:149
StringRef RawBody
Definition Mustache.cpp:174
Type
Definition Mustache.cpp:115
@ Comment
Definition Mustache.cpp:123
@ Partial
Definition Mustache.cpp:118
@ Variable
Definition Mustache.cpp:117
@ SetDelimiter
Definition Mustache.cpp:124
@ SectionClose
Definition Mustache.cpp:120
@ InvertSectionOpen
Definition Mustache.cpp:121
@ Text
Definition Mustache.cpp:116
@ UnescapeVariable
Definition Mustache.cpp:122
@ SectionOpen
Definition Mustache.cpp:119
Token(StringRef Str)
Definition Mustache.cpp:127
Token(StringRef RawBody, StringRef TokenBody, char Identifier, MustacheContext &Ctx)
Definition Mustache.cpp:131
void setIndentation(size_t NewIndentation)
Definition Mustache.cpp:147
Type TokenType
Definition Mustache.cpp:172
StringRef TokenBody
Definition Mustache.cpp:176
static Type getTokenType(char Identifier)
Definition Mustache.cpp:151
ArrayRef< StringRef > AccessorValue
Definition Mustache.cpp:177
ArrayRef< StringRef > getAccessor() const
Definition Mustache.cpp:143
size_t Indentation
Definition Mustache.cpp:178
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream(bool unbuffered=false, OStreamKind K=OStreamKind::OK_OStream)
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
void SetUnbuffered()
Set the stream to be unbuffered.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
static bool hasTextAhead(size_t Idx, const ArrayRef< Token > &Tokens)
Definition Mustache.cpp:294
static AstPtr createRootNode(MustacheContext &Ctx)
Definition Mustache.cpp:252
static const char * tagKindToString(Tag::Kind K)
Definition Mustache.cpp:359
void stripTokenBefore(SmallVectorImpl< Token > &Tokens, size_t Idx, Token &CurrentToken, Token::Type CurrentType)
Definition Mustache.cpp:336
iplist< ASTNode > ASTNodeList
static AstPtr createTextNode(MustacheContext &Ctx, StringRef Body, ASTNode *Parent)
Definition Mustache.cpp:261
static const char * jsonKindToString(json::Value::Kind K)
Definition Mustache.cpp:371
std::function< llvm::json::Value(std::string)> SectionLambda
static AstPtr createNode(MustacheContext &Ctx, ASTNode::Type T, ArrayRef< StringRef > A, ASTNode *Parent)
Definition Mustache.cpp:256
static void stripTokenAhead(SmallVectorImpl< Token > &Tokens, size_t Idx)
Definition Mustache.cpp:320
std::function< llvm::json::Value()> Lambda
static bool hasTextBehind(size_t Idx, const ArrayRef< Token > &Tokens)
Definition Mustache.cpp:278
static bool requiresCleanUp(Token::Type T)
Definition Mustache.cpp:307
static SmallVector< Token > tokenize(StringRef Template, MustacheContext &Ctx)
Definition Mustache.cpp:390
DenseMap< char, std::string > EscapeMap
static void toMustacheString(const json::Value &Data, raw_ostream &OS)
Definition Mustache.cpp:669
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
FunctionAddr VTableAddr Next
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
Definition Mustache.cpp:346
size_t StartPosition
Definition Mustache.cpp:356
StringRef Content
Definition Mustache.cpp:354
StringRef FullMatch
Definition Mustache.cpp:355
Kind
Definition Mustache.cpp:347
@ Triple
Definition Mustache.cpp:350
@ None
Definition Mustache.cpp:348
@ Normal
Definition Mustache.cpp:349
Kind TagKind
Definition Mustache.cpp:353