Coverage Report

Created: 2026-02-26 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsonnet/core/desugarer.cpp
Line
Count
Source
1
/*
2
Copyright 2015 Google Inc. All rights reserved.
3
4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7
8
    http://www.apache.org/licenses/LICENSE-2.0
9
10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16
17
#include <cassert>
18
19
#include <algorithm>
20
21
#include "ast.h"
22
#include "desugarer.h"
23
#include "lexer.h"
24
#include "parser.h"
25
#include "pass.h"
26
#include "string_utils.h"
27
28
namespace jsonnet::internal {
29
30
static const Fodder EF;  // Empty fodder.
31
32
static const LocationRange E;  // Empty.
33
34
struct BuiltinDecl {
35
    UString name;
36
    std::vector<UString> params;
37
};
38
39
static unsigned long max_builtin = 41;
40
BuiltinDecl jsonnet_builtin_decl(unsigned long builtin)
41
882k
{
42
882k
    switch (builtin) {
43
21.0k
        case 0: return {U"makeArray", {U"sz", U"func"}};
44
21.0k
        case 1: return {U"pow", {U"x", U"n"}};
45
21.0k
        case 2: return {U"floor", {U"x"}};
46
21.0k
        case 3: return {U"ceil", {U"x"}};
47
21.0k
        case 4: return {U"sqrt", {U"x"}};
48
21.0k
        case 5: return {U"sin", {U"x"}};
49
21.0k
        case 6: return {U"cos", {U"x"}};
50
21.0k
        case 7: return {U"tan", {U"x"}};
51
21.0k
        case 8: return {U"asin", {U"x"}};
52
21.0k
        case 9: return {U"acos", {U"x"}};
53
21.0k
        case 10: return {U"atan", {U"x"}};
54
21.0k
        case 11: return {U"type", {U"x"}};
55
21.0k
        case 12: return {U"filter", {U"func", U"arr"}};
56
21.0k
        case 13: return {U"objectHasEx", {U"obj", U"f", U"inc_hidden"}};
57
21.0k
        case 14: return {U"length", {U"x"}};
58
21.0k
        case 15: return {U"objectFieldsEx", {U"obj", U"inc_hidden"}};
59
21.0k
        case 16: return {U"codepoint", {U"str"}};
60
21.0k
        case 17: return {U"char", {U"n"}};
61
21.0k
        case 18: return {U"log", {U"n"}};
62
21.0k
        case 19: return {U"exp", {U"n"}};
63
21.0k
        case 20: return {U"mantissa", {U"n"}};
64
21.0k
        case 21: return {U"exponent", {U"n"}};
65
21.0k
        case 22: return {U"modulo", {U"a", U"b"}};
66
21.0k
        case 23: return {U"extVar", {U"x"}};
67
21.0k
        case 24: return {U"primitiveEquals", {U"a", U"b"}};
68
21.0k
        case 25: return {U"native", {U"name"}};
69
21.0k
        case 26: return {U"md5", {U"str"}};
70
21.0k
        case 27: return {U"trace", {U"str", U"rest"}};
71
21.0k
        case 28: return {U"splitLimit", {U"str", U"c", U"maxsplits"}};
72
21.0k
        case 29: return {U"substr", {U"str", U"from", U"len"}};
73
21.0k
        case 30: return {U"range", {U"from", U"to"}};
74
21.0k
        case 31: return {U"strReplace", {U"str", U"from", U"to"}};
75
21.0k
        case 32: return {U"asciiLower", {U"str"}};
76
21.0k
        case 33: return {U"asciiUpper", {U"str"}};
77
21.0k
        case 34: return {U"join", {U"sep", U"arr"}};
78
21.0k
        case 35: return {U"parseJson", {U"str"}};
79
21.0k
        case 36: return {U"parseYaml", {U"str"}};
80
21.0k
        case 37: return {U"encodeUTF8", {U"str"}};
81
21.0k
        case 38: return {U"decodeUTF8", {U"arr"}};
82
21.0k
        case 39: return {U"atan2", {U"y", U"x"}};
83
21.0k
        case 40: return {U"hypot", {U"a", U"b"}};
84
21.0k
        case 41: return {U"objectRemoveKey", {U"obj", U"key"}};
85
0
        default:
86
0
            std::cerr << "INTERNAL ERROR: Unrecognized builtin function: " << builtin << std::endl;
87
0
            std::abort();
88
882k
    }
89
    // Quiet, compiler.
90
0
    return BuiltinDecl();
91
882k
}
92
93
static constexpr char STD_CODE[] = {
94
#include "std.jsonnet.h"
95
};
96
97
/** Desugar Jsonnet expressions to reduce the number of constructs the rest of the implementation
98
 * needs to understand.
99
 *
100
 * Desugaring should happen immediately after parsing, i.e. before static analysis and execution.
101
 * Temporary variables introduced here should be prefixed with $ to ensure they do not clash with
102
 * variables used in user code.
103
 */
104
class Desugarer {
105
    Allocator *alloc;
106
    bool isStdlib;
107
108
    template <class T, class... Args>
109
    T *make(Args &&... args)
110
89.8M
    {
111
89.8M
        return alloc->make<T>(std::forward<Args>(args)...);
112
89.8M
    }
jsonnet::internal::Binary* jsonnet::internal::Desugarer::make<jsonnet::internal::Binary, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp&&, jsonnet::internal::AST*&)
Line
Count
Source
110
215k
    {
111
215k
        return alloc->make<T>(std::forward<Args>(args)...);
112
215k
    }
jsonnet::internal::LiteralNumber* jsonnet::internal::Desugarer::make<jsonnet::internal::LiteralNumber, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, char const (&) [4]>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, char const (&) [4])
Line
Count
Source
110
1.62M
    {
111
1.62M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.62M
    }
jsonnet::internal::Apply* jsonnet::internal::Desugarer::make<jsonnet::internal::Apply, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&)
Line
Count
Source
110
765k
    {
111
765k
        return alloc->make<T>(std::forward<Args>(args)...);
112
765k
    }
jsonnet::internal::Binary* jsonnet::internal::Desugarer::make<jsonnet::internal::Binary, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp&&, jsonnet::internal::AST*&)
Line
Count
Source
110
1.20M
    {
111
1.20M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.20M
    }
jsonnet::internal::Binary* jsonnet::internal::Desugarer::make<jsonnet::internal::Binary, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp, jsonnet::internal::Array*>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp&&, jsonnet::internal::Array*&&)
Line
Count
Source
110
765k
    {
111
765k
        return alloc->make<T>(std::forward<Args>(args)...);
112
765k
    }
jsonnet::internal::Array* jsonnet::internal::Desugarer::make<jsonnet::internal::Array, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Array::Element, std::__1::allocator<jsonnet::internal::Array::Element> >, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Array::Element, std::__1::allocator<jsonnet::internal::Array::Element> >&&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
765k
    {
111
765k
        return alloc->make<T>(std::forward<Args>(args)...);
112
765k
    }
jsonnet::internal::Apply* jsonnet::internal::Desugarer::make<jsonnet::internal::Apply, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&)
Line
Count
Source
110
1.28M
    {
111
1.28M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.28M
    }
jsonnet::internal::Conditional* jsonnet::internal::Desugarer::make<jsonnet::internal::Conditional, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST* const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST* const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&)
Line
Count
Source
110
369k
    {
111
369k
        return alloc->make<T>(std::forward<Args>(args)...);
112
369k
    }
jsonnet::internal::Local* jsonnet::internal::Desugarer::make<jsonnet::internal::Local, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >, jsonnet::internal::Conditional*>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >&&, jsonnet::internal::Conditional*&&)
Line
Count
Source
110
839k
    {
111
839k
        return alloc->make<T>(std::forward<Args>(args)...);
112
839k
    }
jsonnet::internal::Function* jsonnet::internal::Desugarer::make<jsonnet::internal::Function, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Conditional*>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Conditional*&&)
Line
Count
Source
110
839k
    {
111
839k
        return alloc->make<T>(std::forward<Args>(args)...);
112
839k
    }
jsonnet::internal::Conditional* jsonnet::internal::Desugarer::make<jsonnet::internal::Conditional, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Binary*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Local*>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Binary*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Local*&&)
Line
Count
Source
110
839k
    {
111
839k
        return alloc->make<T>(std::forward<Args>(args)...);
112
839k
    }
jsonnet::internal::Binary* jsonnet::internal::Desugarer::make<jsonnet::internal::Binary, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp, jsonnet::internal::Apply*>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp&&, jsonnet::internal::Apply*&&)
Line
Count
Source
110
839k
    {
111
839k
        return alloc->make<T>(std::forward<Args>(args)...);
112
839k
    }
jsonnet::internal::Local* jsonnet::internal::Desugarer::make<jsonnet::internal::Local, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >&&, jsonnet::internal::AST*&)
Line
Count
Source
110
862k
    {
111
862k
        return alloc->make<T>(std::forward<Args>(args)...);
112
862k
    }
jsonnet::internal::Index* jsonnet::internal::Desugarer::make<jsonnet::internal::Index, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
839k
    {
111
839k
        return alloc->make<T>(std::forward<Args>(args)...);
112
839k
    }
jsonnet::internal::Conditional* jsonnet::internal::Desugarer::make<jsonnet::internal::Conditional, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Apply*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Apply*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Error*>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Apply*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Apply*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Error*&&)
Line
Count
Source
110
839k
    {
111
839k
        return alloc->make<T>(std::forward<Args>(args)...);
112
839k
    }
jsonnet::internal::Array* jsonnet::internal::Desugarer::make<jsonnet::internal::Array, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Array::Element, std::__1::allocator<jsonnet::internal::Array::Element> >, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Array::Element, std::__1::allocator<jsonnet::internal::Array::Element> >&&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
765k
    {
111
765k
        return alloc->make<T>(std::forward<Args>(args)...);
112
765k
    }
jsonnet::internal::LiteralString* jsonnet::internal::Desugarer::make<jsonnet::internal::LiteralString, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> > const&, jsonnet::internal::LiteralString::TokenKind, char const (&) [1], char const (&) [1]>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> > const&, jsonnet::internal::LiteralString::TokenKind&&, char const (&) [1], char const (&) [1])
Line
Count
Source
110
30.0M
    {
111
30.0M
        return alloc->make<T>(std::forward<Args>(args)...);
112
30.0M
    }
jsonnet::internal::Error* jsonnet::internal::Desugarer::make<jsonnet::internal::Error, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&)
Line
Count
Source
110
1.77M
    {
111
1.77M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.77M
    }
jsonnet::internal::Conditional* jsonnet::internal::Desugarer::make<jsonnet::internal::Conditional, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&)
Line
Count
Source
110
862k
    {
111
862k
        return alloc->make<T>(std::forward<Args>(args)...);
112
862k
    }
jsonnet::internal::Index* jsonnet::internal::Desugarer::make<jsonnet::internal::Index, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool, jsonnet::internal::LiteralString*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&, jsonnet::internal::LiteralString*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
7.42M
    {
111
7.42M
        return alloc->make<T>(std::forward<Args>(args)...);
112
7.42M
    }
jsonnet::internal::Apply* jsonnet::internal::Desugarer::make<jsonnet::internal::Apply, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&)
Line
Count
Source
110
666k
    {
111
666k
        return alloc->make<T>(std::forward<Args>(args)...);
112
666k
    }
jsonnet::internal::Apply* jsonnet::internal::Desugarer::make<jsonnet::internal::Apply, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Index*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Index*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&)
Line
Count
Source
110
4.67M
    {
111
4.67M
        return alloc->make<T>(std::forward<Args>(args)...);
112
4.67M
    }
jsonnet::internal::Unary* jsonnet::internal::Desugarer::make<jsonnet::internal::Unary, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::UnaryOp, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::UnaryOp&&, jsonnet::internal::AST*&)
Line
Count
Source
110
515k
    {
111
515k
        return alloc->make<T>(std::forward<Args>(args)...);
112
515k
    }
jsonnet::internal::LiteralNull* jsonnet::internal::Desugarer::make<jsonnet::internal::LiteralNull, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
716k
    {
111
716k
        return alloc->make<T>(std::forward<Args>(args)...);
112
716k
    }
jsonnet::internal::Var* jsonnet::internal::Desugarer::make<jsonnet::internal::Var, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Identifier const*&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Identifier const*&)
Line
Count
Source
110
17.3M
    {
111
17.3M
        return alloc->make<T>(std::forward<Args>(args)...);
112
17.3M
    }
jsonnet::internal::Apply* jsonnet::internal::Desugarer::make<jsonnet::internal::Apply, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Index*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Index*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&)
Line
Count
Source
110
2.07M
    {
111
2.07M
        return alloc->make<T>(std::forward<Args>(args)...);
112
2.07M
    }
jsonnet::internal::Function* jsonnet::internal::Desugarer::make<jsonnet::internal::Function, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&)
Line
Count
Source
110
1.55M
    {
111
1.55M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.55M
    }
jsonnet::internal::Self* jsonnet::internal::Desugarer::make<jsonnet::internal::Self, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
79.5k
    {
111
79.5k
        return alloc->make<T>(std::forward<Args>(args)...);
112
79.5k
    }
jsonnet::internal::Conditional* jsonnet::internal::Desugarer::make<jsonnet::internal::Conditional, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::LiteralBoolean*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Error*>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::LiteralBoolean*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Error*&&)
Line
Count
Source
110
69.4k
    {
111
69.4k
        return alloc->make<T>(std::forward<Args>(args)...);
112
69.4k
    }
jsonnet::internal::LiteralBoolean* jsonnet::internal::Desugarer::make<jsonnet::internal::LiteralBoolean, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&)
Line
Count
Source
110
69.4k
    {
111
69.4k
        return alloc->make<T>(std::forward<Args>(args)...);
112
69.4k
    }
jsonnet::internal::Function* jsonnet::internal::Desugarer::make<jsonnet::internal::Function, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::AST*&)
Line
Count
Source
110
2.65M
    {
111
2.65M
        return alloc->make<T>(std::forward<Args>(args)...);
112
2.65M
    }
jsonnet::internal::Conditional* jsonnet::internal::Desugarer::make<jsonnet::internal::Conditional, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::InSuper*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Binary*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::InSuper*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Binary*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&&)
Line
Count
Source
110
42.8k
    {
111
42.8k
        return alloc->make<T>(std::forward<Args>(args)...);
112
42.8k
    }
jsonnet::internal::InSuper* jsonnet::internal::Desugarer::make<jsonnet::internal::InSuper, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
42.8k
    {
111
42.8k
        return alloc->make<T>(std::forward<Args>(args)...);
112
42.8k
    }
jsonnet::internal::Binary* jsonnet::internal::Desugarer::make<jsonnet::internal::Binary, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::SuperIndex*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::SuperIndex*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::BinaryOp&&, jsonnet::internal::AST*&)
Line
Count
Source
110
42.8k
    {
111
42.8k
        return alloc->make<T>(std::forward<Args>(args)...);
112
42.8k
    }
jsonnet::internal::SuperIndex* jsonnet::internal::Desugarer::make<jsonnet::internal::SuperIndex, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::AST*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&)
Line
Count
Source
110
42.8k
    {
111
42.8k
        return alloc->make<T>(std::forward<Args>(args)...);
112
42.8k
    }
jsonnet::internal::DesugaredObject* jsonnet::internal::Desugarer::make<jsonnet::internal::DesugaredObject, jsonnet::internal::LocationRange&, std::__1::list<jsonnet::internal::AST*, std::__1::allocator<jsonnet::internal::AST*> >&, std::__1::vector<jsonnet::internal::DesugaredObject::Field, std::__1::allocator<jsonnet::internal::DesugaredObject::Field> >&>(jsonnet::internal::LocationRange&, std::__1::list<jsonnet::internal::AST*, std::__1::allocator<jsonnet::internal::AST*> >&, std::__1::vector<jsonnet::internal::DesugaredObject::Field, std::__1::allocator<jsonnet::internal::DesugaredObject::Field> >&)
Line
Count
Source
110
1.13M
    {
111
1.13M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.13M
    }
jsonnet::internal::Local* jsonnet::internal::Desugarer::make<jsonnet::internal::Local, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >&, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >&, jsonnet::internal::AST*&)
Line
Count
Source
110
2.84M
    {
111
2.84M
        return alloc->make<T>(std::forward<Args>(args)...);
112
2.84M
    }
jsonnet::internal::Index* jsonnet::internal::Desugarer::make<jsonnet::internal::Index, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool, jsonnet::internal::LiteralNumber*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&, jsonnet::internal::LiteralNumber*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
102k
    {
111
102k
        return alloc->make<T>(std::forward<Args>(args)...);
112
102k
    }
jsonnet::internal::LiteralNumber* jsonnet::internal::Desugarer::make<jsonnet::internal::LiteralNumber, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Line
Count
Source
110
102k
    {
111
102k
        return alloc->make<T>(std::forward<Args>(args)...);
112
102k
    }
jsonnet::internal::ArrayComprehension* jsonnet::internal::Desugarer::make<jsonnet::internal::ArrayComprehension, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Array*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool, std::__1::vector<jsonnet::internal::ComprehensionSpec, std::__1::allocator<jsonnet::internal::ComprehensionSpec> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Array*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&, std::__1::vector<jsonnet::internal::ComprehensionSpec, std::__1::allocator<jsonnet::internal::ComprehensionSpec> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
92.9k
    {
111
92.9k
        return alloc->make<T>(std::forward<Args>(args)...);
112
92.9k
    }
jsonnet::internal::Array* jsonnet::internal::Desugarer::make<jsonnet::internal::Array, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Array::Element, std::__1::allocator<jsonnet::internal::Array::Element> >&, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::Array::Element, std::__1::allocator<jsonnet::internal::Array::Element> >&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
92.9k
    {
111
92.9k
        return alloc->make<T>(std::forward<Args>(args)...);
112
92.9k
    }
jsonnet::internal::ObjectComprehensionSimple* jsonnet::internal::Desugarer::make<jsonnet::internal::ObjectComprehensionSimple, jsonnet::internal::LocationRange&, jsonnet::internal::Index*, jsonnet::internal::Local*, jsonnet::internal::Identifier const*&, jsonnet::internal::AST*&>(jsonnet::internal::LocationRange&, jsonnet::internal::Index*&&, jsonnet::internal::Local*&&, jsonnet::internal::Identifier const*&, jsonnet::internal::AST*&)
Line
Count
Source
110
92.9k
    {
111
92.9k
        return alloc->make<T>(std::forward<Args>(args)...);
112
92.9k
    }
jsonnet::internal::Index* jsonnet::internal::Desugarer::make<jsonnet::internal::Index, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr), std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&, jsonnet::internal::AST*&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, decltype(nullptr)&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&)
Line
Count
Source
110
92.9k
    {
111
92.9k
        return alloc->make<T>(std::forward<Args>(args)...);
112
92.9k
    }
jsonnet::internal::BuiltinFunction* jsonnet::internal::Desugarer::make<jsonnet::internal::BuiltinFunction, jsonnet::internal::LocationRange const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::vector<jsonnet::internal::Identifier const*, std::__1::allocator<jsonnet::internal::Identifier const*> >&>(jsonnet::internal::LocationRange const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&, std::__1::vector<jsonnet::internal::Identifier const*, std::__1::allocator<jsonnet::internal::Identifier const*> >&)
Line
Count
Source
110
882k
    {
111
882k
        return alloc->make<T>(std::forward<Args>(args)...);
112
882k
    }
jsonnet::internal::Local* jsonnet::internal::Desugarer::make<jsonnet::internal::Local, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >, jsonnet::internal::Conditional*>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::Local::Bind, std::__1::allocator<jsonnet::internal::Local::Bind> >&&, jsonnet::internal::Conditional*&&)
Line
Count
Source
110
11.4k
    {
111
11.4k
        return alloc->make<T>(std::forward<Args>(args)...);
112
11.4k
    }
jsonnet::internal::Conditional* jsonnet::internal::Desugarer::make<jsonnet::internal::Conditional, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::Apply*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Apply*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::Var*>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::Apply*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Apply*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::Var*&&)
Line
Count
Source
110
11.4k
    {
111
11.4k
        return alloc->make<T>(std::forward<Args>(args)...);
112
11.4k
    }
jsonnet::internal::Apply* jsonnet::internal::Desugarer::make<jsonnet::internal::Apply, jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool>(jsonnet::internal::LocationRange&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, jsonnet::internal::Var*&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::ArgParam, std::__1::allocator<jsonnet::internal::ArgParam> >&, bool&&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, bool&&)
Line
Count
Source
110
11.4k
    {
111
11.4k
        return alloc->make<T>(std::forward<Args>(args)...);
112
11.4k
    }
jsonnet::internal::Var* jsonnet::internal::Desugarer::make<jsonnet::internal::Var, jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::Identifier const*&>(jsonnet::internal::LocationRange const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::Identifier const*&)
Line
Count
Source
110
22.8k
    {
111
22.8k
        return alloc->make<T>(std::forward<Args>(args)...);
112
22.8k
    }
113
114
    AST *clone(AST *ast)
115
128k
    {
116
128k
        return clone_ast(*alloc, ast);
117
128k
    }
118
119
    const Identifier *id(const UString &s)
120
13.5M
    {
121
13.5M
        return alloc->makeIdentifier(s);
122
13.5M
    }
123
124
    LiteralString *str(const UString &s)
125
24.3M
    {
126
24.3M
        return make<LiteralString>(E, EF, s, LiteralString::RAW_DESUGARED, "", "");
127
24.3M
    }
128
129
    LiteralString *str(const LocationRange &loc, const UString &s)
130
5.64M
    {
131
5.64M
        return make<LiteralString>(loc, EF, s, LiteralString::RAW_DESUGARED, "", "");
132
5.64M
    }
133
134
    LiteralNull *null(void)
135
716k
    {
136
716k
        return make<LiteralNull>(E, EF);
137
716k
    }
138
139
    Var *var(const Identifier *ident)
140
17.3M
    {
141
17.3M
        return make<Var>(E, EF, ident);
142
17.3M
    }
143
144
    Var *std(void)
145
7.43M
    {
146
        // In most places, there is a "$std" variable inserted by
147
        // the desugarer. On the standard library itself there isn't,
148
        // so use "std" instead.
149
7.43M
        return var(id(isStdlib ? U"std" : U"$std"));
150
7.43M
    }
151
152
    Local::Bind bind(const Identifier *id, AST *body)
153
3.40M
    {
154
3.40M
        return Local::Bind(EF, id, EF, body, false, EF, ArgParams{}, false, EF, EF);
155
3.40M
    }
156
157
    Local::Binds singleBind(const Identifier *id, AST *body)
158
873k
    {
159
873k
        return {bind(id, body)};
160
873k
    }
161
162
    Array *singleton(AST *body)
163
765k
    {
164
765k
        return make<Array>(
165
765k
            body->location, EF, Array::Elements{Array::Element(body, EF)}, false, EF);
166
765k
    }
167
168
    Apply *stdFunc(const UString &name, AST *v)
169
1.69M
    {
170
1.69M
        return make<Apply>(
171
1.69M
            v->location,
172
1.69M
            EF,
173
1.69M
            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
174
1.69M
            EF,
175
1.69M
            ArgParams{{v, EF}},
176
1.69M
            false,  // trailingComma
177
1.69M
            EF,
178
1.69M
            EF,
179
1.69M
            true  // tailstrict
180
1.69M
        );
181
1.69M
    }
182
183
    Apply *stdFunc(const LocationRange &loc, const UString &name, AST *a, AST *b)
184
4.67M
    {
185
4.67M
        return make<Apply>(
186
4.67M
            loc,
187
4.67M
            EF,
188
4.67M
            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
189
4.67M
            EF,
190
4.67M
            ArgParams{{a, EF}, {b, EF}},
191
4.67M
            false,  // trailingComma
192
4.67M
            EF,
193
4.67M
            EF,
194
4.67M
            true  // tailstrict
195
4.67M
        );
196
4.67M
    }
197
198
    Apply *length(AST *v)
199
839k
    {
200
839k
        return stdFunc(U"length", v);
201
839k
    }
202
203
    Apply *type(AST *v)
204
851k
    {
205
851k
        return stdFunc(U"type", v);
206
851k
    }
207
208
    Apply *primitiveEquals(const LocationRange &loc, AST *a, AST *b)
209
11.4k
    {
210
11.4k
        return stdFunc(loc, U"primitiveEquals", a, b);
211
11.4k
    }
212
213
    Apply *equals(const LocationRange &loc, AST *a, AST *b)
214
4.66M
    {
215
4.66M
        return stdFunc(loc, U"equals", a, b);
216
4.66M
    }
217
218
    Error *error(AST *msg)
219
908k
    {
220
908k
        return make<Error>(msg->location, EF, msg);
221
908k
    }
222
223
    Error *error(const LocationRange &loc, const UString &msg)
224
839k
    {
225
839k
        return error(str(loc, msg));
226
839k
    }
227
228
   public:
229
22.2k
    Desugarer(Allocator *alloc, bool isStdlib = false) : alloc(alloc), isStdlib(isStdlib) {}
230
231
    void desugarParams(ArgParams &params, unsigned obj_level)
232
7.43M
    {
233
9.38M
        for (auto &param : params) {
234
9.38M
            if (param.expr) {
235
                // Default arg.
236
447k
                desugar(param.expr, obj_level);
237
447k
            }
238
9.38M
        }
239
7.43M
    }
240
241
    // For all occurrences, records the identifier that will replace super[e]
242
    // If self occurs, also map the self identifier to nullptr.
243
    typedef std::vector<std::pair<const Identifier *, AST *>> SuperVars;
244
245
    SuperVars desugarFields(AST *ast, ObjectFields &fields, unsigned obj_level)
246
1.22M
    {
247
        // Desugar children
248
5.36M
        for (auto &field : fields) {
249
5.36M
            if (field.expr1 != nullptr)
250
298k
                desugar(field.expr1, obj_level);
251
5.36M
            desugar(field.expr2, obj_level + 1);
252
5.36M
            if (field.expr3 != nullptr)
253
36.0k
                desugar(field.expr3, obj_level + 1);
254
5.36M
            desugarParams(field.params, obj_level + 1);
255
5.36M
        }
256
257
        // Simplify asserts
258
5.36M
        for (auto &field : fields) {
259
5.36M
            if (field.kind != ObjectField::ASSERT)
260
5.29M
                continue;
261
69.4k
            AST *msg = field.expr3;
262
69.4k
            field.expr3 = nullptr;
263
69.4k
            if (msg == nullptr) {
264
                // The location is what appears in the stacktrace.
265
33.3k
                msg = str(field.expr2->location, U"Object assertion failed.");
266
33.3k
            }
267
268
            // if expr2 then true else error msg
269
69.4k
            field.expr2 = make<Conditional>(field.expr2->location,
270
69.4k
                                            EF,
271
69.4k
                                            field.expr2,
272
69.4k
                                            EF,
273
69.4k
                                            make<LiteralBoolean>(E, EF, true),
274
69.4k
                                            EF,
275
69.4k
                                            error(msg));
276
69.4k
        }
277
278
        // Remove methods
279
5.36M
        for (auto &field : fields) {
280
5.36M
            if (!field.methodSugar)
281
2.70M
                continue;
282
2.65M
            field.expr2 = make<Function>(field.expr2->location,
283
2.65M
                                         EF,
284
2.65M
                                         field.fodderL,
285
2.65M
                                         field.params,
286
2.65M
                                         field.trailingComma,
287
2.65M
                                         field.fodderR,
288
2.65M
                                         field.expr2);
289
2.65M
            field.methodSugar = false;
290
2.65M
            field.params.clear();
291
2.65M
        }
292
293
        // Remove object-level locals
294
1.22M
        auto copy = fields;
295
1.22M
        fields.clear();
296
1.22M
        Local::Binds binds;
297
5.36M
        for (auto &local : copy) {
298
5.36M
            if (local.kind != ObjectField::LOCAL)
299
5.13M
                continue;
300
225k
            binds.push_back(bind(local.id, local.expr2));
301
225k
        }
302
5.36M
        for (auto &field : copy) {
303
5.36M
            if (field.kind == ObjectField::LOCAL)
304
225k
                continue;
305
5.13M
            if (!binds.empty())
306
2.74M
                field.expr2 = make<Local>(field.expr2->location, EF, binds, field.expr2);
307
5.13M
            fields.push_back(field);
308
5.13M
        }
309
310
        // Change all to FIELD_EXPR
311
5.13M
        for (auto &field : fields) {
312
5.13M
            switch (field.kind) {
313
69.4k
                case ObjectField::ASSERT:
314
                    // Nothing to do.
315
69.4k
                    break;
316
317
4.76M
                case ObjectField::FIELD_ID:
318
4.76M
                    field.expr1 = str(field.idLocation, field.id->name);
319
4.76M
                    field.kind = ObjectField::FIELD_EXPR;
320
4.76M
                    break;
321
322
102k
                case ObjectField::FIELD_EXPR:
323
                    // Nothing to do.
324
102k
                    break;
325
326
195k
                case ObjectField::FIELD_STR:
327
                    // Just set the flag.
328
195k
                    field.kind = ObjectField::FIELD_EXPR;
329
195k
                    break;
330
331
0
                case ObjectField::LOCAL:
332
0
                    std::cerr << "Locals should be removed by now." << std::endl;
333
0
                    abort();
334
5.13M
            }
335
5.13M
        }
336
337
        /** Replaces all occurrences of self, super[f] and e in super with variables.
338
         *
339
         * Returns all variables and original expressions via super_vars.
340
         */
341
1.22M
        class SubstituteSelfSuper : public CompilerPass {
342
1.22M
            Desugarer *desugarer;
343
1.22M
            SuperVars &superVars;
344
1.22M
            unsigned &counter;
345
1.22M
            const Identifier *newSelf;
346
347
1.22M
           public:
348
1.22M
            SubstituteSelfSuper(Desugarer *desugarer, SuperVars &super_vars, unsigned &counter)
349
1.22M
                : CompilerPass(*desugarer->alloc),
350
1.22M
                  desugarer(desugarer),
351
1.22M
                  superVars(super_vars),
352
1.22M
                  counter(counter),
353
1.22M
                  newSelf(nullptr)
354
1.22M
            {
355
42.8k
            }
356
1.22M
            void visitExpr(AST *&expr)
357
3.96M
            {
358
3.96M
                if (dynamic_cast<Self *>(expr)) {
359
10.3k
                    if (newSelf == nullptr) {
360
1.67k
                        newSelf = desugarer->id(U"$outer_self");
361
1.67k
                        superVars.emplace_back(newSelf, nullptr);
362
1.67k
                    }
363
10.3k
                    expr = alloc.make<Var>(expr->location, expr->openFodder, newSelf);
364
3.95M
                } else if (auto *super_index = dynamic_cast<SuperIndex *>(expr)) {
365
285k
                    UStringStream ss;
366
285k
                    ss << U"$outer_super_index" << (counter++);
367
285k
                    const Identifier *super_var = desugarer->id(ss.str());
368
                    // Desugaring of expr should already have occurred.
369
285k
                    assert(super_index->index != nullptr);
370
                    // Re-use super_index since we're replacing it here.
371
285k
                    superVars.emplace_back(super_var, super_index);
372
285k
                    expr = alloc.make<Var>(expr->location, expr->openFodder, super_var);
373
3.66M
                } else if (auto *in_super = dynamic_cast<InSuper *>(expr)) {
374
274k
                    UStringStream ss;
375
274k
                    ss << U"$outer_in_super" << (counter++);
376
274k
                    const Identifier *in_super_var = desugarer->id(ss.str());
377
                    // Re-use in_super since we're replacing it here.
378
274k
                    superVars.emplace_back(in_super_var, in_super);
379
274k
                    expr = alloc.make<Var>(expr->location, expr->openFodder, in_super_var);
380
274k
                }
381
3.96M
                CompilerPass::visitExpr(expr);
382
3.96M
            }
383
1.22M
        };
384
385
1.22M
        SuperVars super_vars;
386
1.22M
        unsigned counter = 0;
387
388
        // Remove +:
389
5.13M
        for (auto &field : fields) {
390
5.13M
            if (!field.superSugar)
391
5.09M
                continue;
392
            // We have to bind self/super from expr1 outside the class, as we copy the expression
393
            // into the field body.
394
            // Clone it so that we maintain the AST as a tree.
395
42.8k
            AST *index = clone(field.expr1);
396
            // This will remove self/super.
397
42.8k
            SubstituteSelfSuper(this, super_vars, counter).expr(index);
398
42.8k
            field.expr2 = make<Conditional>(
399
42.8k
                ast->location,
400
42.8k
                EF,
401
42.8k
                make<InSuper>(ast->location, EF, index, EF, EF),
402
42.8k
                EF,
403
42.8k
                make<Binary>(ast->location,
404
42.8k
                             EF,
405
42.8k
                             make<SuperIndex>(ast->location, EF, EF, clone(index), EF, nullptr),
406
42.8k
                             EF,
407
42.8k
                             BOP_PLUS,
408
42.8k
                             field.expr2),
409
42.8k
                EF,
410
42.8k
                clone(field.expr2));
411
42.8k
            field.superSugar = false;
412
42.8k
        }
413
414
1.22M
        return super_vars;
415
1.22M
    }
416
417
765k
    AST* makeArrayComprehension(ArrayComprehension *ast) {
418
765k
        int n = ast->specs.size();
419
765k
        AST *zero = make<LiteralNumber>(E, EF, "0.0");
420
765k
        AST *one = make<LiteralNumber>(E, EF, "1.0");
421
765k
        auto *_r = id(U"$r");
422
765k
        auto *_l = id(U"$l");
423
765k
        std::vector<const Identifier *> _i(n);
424
1.97M
        for (int i = 0; i < n; ++i) {
425
1.20M
            UStringStream ss;
426
1.20M
            ss << U"$i_" << i;
427
1.20M
            _i[i] = id(ss.str());
428
1.20M
        }
429
765k
        std::vector<const Identifier *> _aux(n);
430
1.97M
        for (int i = 0; i < n; ++i) {
431
1.20M
            UStringStream ss;
432
1.20M
            ss << U"$aux_" << i;
433
1.20M
            _aux[i] = id(ss.str());
434
1.20M
        }
435
436
        // Build it from the inside out.  We keep wrapping 'in' with more ASTs.
437
765k
        assert(ast->specs[0].kind == ComprehensionSpec::FOR);
438
439
765k
        int last_for = n - 1;
440
1.12M
        while (ast->specs[last_for].kind != ComprehensionSpec::FOR)
441
362k
            last_for--;
442
        // $aux_{last_for}($i_{last_for} + 1, $r + [body])
443
765k
        AST *in = make<Apply>(
444
765k
            ast->body->location,
445
765k
            EF,
446
765k
            var(_aux[last_for]),
447
765k
            EF,
448
765k
            ArgParams{{make<Binary>(E, EF, var(_i[last_for]), EF, BOP_PLUS, one), EF},
449
765k
                {make<Binary>(E, EF, var(_r), EF, BOP_PLUS, singleton(ast->body)), EF}},
450
765k
            false,  // trailingComma
451
765k
            EF,
452
765k
            EF,
453
765k
            true  // tailstrict
454
765k
        );
455
1.97M
        for (int i = n - 1; i >= 0; --i) {
456
1.20M
            const ComprehensionSpec &spec = ast->specs[i];
457
1.20M
            AST *out;
458
1.20M
            if (i > 0) {
459
443k
                int prev_for = i - 1;
460
2.18G
                while (ast->specs[prev_for].kind != ComprehensionSpec::FOR)
461
2.18G
                    prev_for--;
462
463
                // aux_{prev_for}($i_{prev_for} + 1, $r)
464
443k
                out = make<Apply>(  // False branch.
465
443k
                    E,
466
443k
                    EF,
467
443k
                    var(_aux[prev_for]),
468
443k
                    EF,
469
443k
                    ArgParams{{
470
443k
                        make<Binary>(E, EF, var(_i[prev_for]), EF, BOP_PLUS, one),
471
443k
                            EF,
472
443k
                            },
473
443k
                      {
474
443k
                        var(_r),
475
443k
                            EF,
476
443k
                            }},
477
443k
                    false,  // trailingComma
478
443k
                    EF,
479
443k
                    EF,
480
443k
                    true  // tailstrict
481
443k
                );
482
765k
            } else {
483
765k
                out = var(_r);
484
765k
            }
485
1.20M
            switch (spec.kind) {
486
369k
                case ComprehensionSpec::IF: {
487
                  /*
488
                    if [[[...cond...]]] then
489
                    [[[...in...]]]
490
                    else
491
                    [[[...out...]]]
492
                  */
493
369k
                    in = make<Conditional>(ast->location,
494
369k
                                           EF,
495
369k
                                           spec.expr,
496
369k
                                           EF,
497
369k
                                           in,  // True branch.
498
369k
                                           EF,
499
369k
                                           out);  // False branch.
500
369k
                } break;
501
839k
                case ComprehensionSpec::FOR: {
502
                    /*
503
                      local $l = [[[...array...]]]
504
                      aux_{i}(i_{i}, r) =
505
                      if i_{i} >= std.length($l) then
506
                      [[[...out...]]]
507
                      else
508
                      local [[[...var...]]] = $l[i_{i}];
509
                      [[[...in...]]];
510
                      if std.type($l) == "array" then
511
                      aux_{i}(0, $r) tailstrict
512
                      else
513
                      error "In comprehension, can only iterate over array..";
514
                    */
515
839k
                    in = make<Local>(
516
839k
                        ast->location,
517
839k
                        EF,
518
839k
                        Local::Binds{
519
839k
                          bind(_l, spec.expr),  // Need to check expr is an array
520
839k
                              bind(_aux[i],
521
839k
                                   make<Function>(
522
839k
                                       ast->location,
523
839k
                                       EF,
524
839k
                                       EF,
525
839k
                                       ArgParams{{EF, _i[i], EF}, {EF, _r, EF}},
526
839k
                                       false,  // trailingComma
527
839k
                                       EF,
528
839k
                                       make<Conditional>(ast->location,
529
839k
                                                         EF,
530
839k
                                                         make<Binary>(E,
531
839k
                                                                      EF,
532
839k
                                                                      var(_i[i]),
533
839k
                                                                      EF,
534
839k
                                                                      BOP_GREATER_EQ,
535
839k
                                                                      length(var(_l))),
536
839k
                                                         EF,
537
839k
                                                         out,
538
839k
                                                         EF,
539
839k
                                                         make<Local>(
540
839k
                                                             ast->location,
541
839k
                                                             EF,
542
839k
                                                             singleBind(spec.var,
543
839k
                                                                        make<Index>(E,
544
839k
                                                                                    EF,
545
839k
                                                                                    var(_l),
546
839k
                                                                                    EF,
547
839k
                                                                                    false,
548
839k
                                                                                    var(_i[i]),
549
839k
                                                                                    EF,
550
839k
                                                                                    nullptr,
551
839k
                                                                                    EF,
552
839k
                                                                                    nullptr,
553
839k
                                                                                    EF)),
554
839k
                                                             in))))},
555
839k
                        make<Conditional>(
556
839k
                            ast->location,
557
839k
                            EF,
558
839k
                            equals(ast->location, type(var(_l)), str(U"array")),
559
839k
                            EF,
560
839k
                            make<Apply>(
561
839k
                                E,
562
839k
                                EF,
563
839k
                                var(_aux[i]),
564
839k
                                EF,
565
839k
                                ArgParams{{zero, EF},
566
839k
                                  {
567
839k
                                    i == 0 ? make<Array>(
568
765k
                                        E, EF, Array::Elements{}, false, EF)
569
839k
                                        : static_cast<AST *>(var(_r)),
570
839k
                                        EF,
571
839k
                                        }},
572
839k
                                false,  // trailingComma
573
839k
                                EF,
574
839k
                                EF,
575
839k
                                true),  // tailstrict
576
839k
                            EF,
577
839k
                            error(ast->location,
578
839k
                                  U"In comprehension, can only iterate over array.")));
579
839k
                } break;
580
1.20M
            }
581
1.20M
        }
582
583
765k
        return in;
584
765k
    }
585
586
1.13M
    AST* makeObject(Object *ast, unsigned obj_level) {
587
        // Hidden variable to allow outer/top binding.
588
1.13M
        if (obj_level == 0) {
589
76.7k
            const Identifier *hidden_var = id(U"$");
590
76.7k
            auto *body = make<Self>(E, EF);
591
76.7k
            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
592
76.7k
        }
593
594
1.13M
        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
595
596
1.13M
        DesugaredObject::Fields new_fields;
597
1.13M
        ASTs new_asserts;
598
5.04M
        for (const ObjectField &field : ast->fields) {
599
5.04M
            if (field.kind == ObjectField::ASSERT) {
600
69.4k
                new_asserts.push_back(field.expr2);
601
4.97M
            } else if (field.kind == ObjectField::FIELD_EXPR) {
602
4.97M
                new_fields.emplace_back(field.hide, field.expr1, field.expr2);
603
4.97M
            } else {
604
0
                std::cerr << "INTERNAL ERROR: field should have been desugared: " << field.kind
605
0
                          << std::endl;
606
0
            }
607
5.04M
        }
608
609
1.13M
        AST* retval = make<DesugaredObject>(ast->location, new_asserts, new_fields);
610
1.13M
        if (svs.size() > 0) {
611
6.24k
            Local::Binds binds;
612
519k
            for (const auto &pair : svs) {
613
519k
                if (pair.second == nullptr) {
614
                    // Self binding
615
1.49k
                    binds.push_back(bind(pair.first, make<Self>(E, EF)));
616
517k
                } else {
617
                    // Super binding
618
517k
                    binds.push_back(bind(pair.first, pair.second));
619
517k
                }
620
519k
            }
621
6.24k
            retval = make<Local>(ast->location, EF, binds, retval);
622
6.24k
        }
623
624
1.13M
        return retval;
625
1.13M
    }
626
627
92.9k
    AST* makeObjectComprehension(ObjectComprehension *ast, unsigned obj_level) {
628
        // Hidden variable to allow outer/top binding.
629
92.9k
        if (obj_level == 0) {
630
1.33k
            const Identifier *hidden_var = id(U"$");
631
1.33k
            auto *body = make<Self>(E, EF);
632
1.33k
            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
633
1.33k
        }
634
635
92.9k
        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
636
637
92.9k
        AST *field = ast->fields.front().expr1;
638
92.9k
        AST *value = ast->fields.front().expr2;
639
640
        /*  {
641
            [arr[0]]: local x = arr[1], y = arr[2], z = arr[3]; val_expr
642
            for arr in [ [key_expr, x, y, z] for ...  ]
643
            }
644
        */
645
92.9k
        auto *_arr = id(U"$arr");
646
92.9k
        AST *zero = make<LiteralNumber>(E, EF, "0.0");
647
92.9k
        int counter = 1;
648
92.9k
        Local::Binds binds;
649
92.9k
        Array::Elements arr_e{Array::Element(field, EF)};
650
127k
        for (ComprehensionSpec &spec : ast->specs) {
651
127k
            if (spec.kind == ComprehensionSpec::FOR) {
652
102k
                std::stringstream num;
653
102k
                num << counter++;
654
102k
                binds.push_back(bind(spec.var,
655
102k
                                     make<Index>(E,
656
102k
                                                 EF,
657
102k
                                                 var(_arr),
658
102k
                                                 EF,
659
102k
                                                 false,
660
102k
                                                 make<LiteralNumber>(E, EF, num.str()),
661
102k
                                                 EF,
662
102k
                                                 nullptr,
663
102k
                                                 EF,
664
102k
                                                 nullptr,
665
102k
                                                 EF)));
666
102k
                arr_e.emplace_back(var(spec.var), EF);
667
102k
            }
668
127k
        }
669
92.9k
        AST *arr = make<ArrayComprehension>(ast->location,
670
92.9k
                                            EF,
671
92.9k
                                            make<Array>(ast->location, EF, arr_e, false, EF),
672
92.9k
                                            EF,
673
92.9k
                                            false,
674
92.9k
                                            ast->specs,
675
92.9k
                                            EF);
676
92.9k
        desugar(arr, obj_level);
677
92.9k
        return make<ObjectComprehensionSimple>(
678
92.9k
            ast->location,
679
92.9k
            make<Index>(E, EF, var(_arr), EF, false, zero, EF, nullptr, EF, nullptr, EF),
680
92.9k
            make<Local>(ast->location, EF, binds, value),
681
92.9k
            _arr,
682
92.9k
            arr);
683
92.9k
    }
684
685
    void desugar(AST *&ast_, unsigned obj_level)
686
174M
    {
687
174M
        if (auto *ast = dynamic_cast<Apply *>(ast_)) {
688
17.1M
            desugar(ast->target, obj_level);
689
17.1M
            for (ArgParam &arg : ast->args)
690
28.4M
                desugar(arg.expr, obj_level);
691
692
157M
        } else if (auto *ast = dynamic_cast<ApplyBrace *>(ast_)) {
693
216k
            desugar(ast->left, obj_level);
694
216k
            desugar(ast->right, obj_level);
695
216k
            ast_ =
696
216k
                make<Binary>(ast->location, ast->openFodder, ast->left, EF, BOP_PLUS, ast->right);
697
698
157M
        } else if (auto *ast = dynamic_cast<Array *>(ast_)) {
699
2.41M
            for (auto &el : ast->elements)
700
5.51M
                desugar(el.expr, obj_level);
701
702
155M
        } else if (auto *ast = dynamic_cast<ArrayComprehension *>(ast_)) {
703
765k
            for (ComprehensionSpec &spec : ast->specs)
704
1.20M
                desugar(spec.expr, obj_level);
705
765k
            desugar(ast->body, obj_level + 1);
706
707
765k
            ast_ = makeArrayComprehension(ast);
708
709
154M
        } else if (auto *ast = dynamic_cast<Assert *>(ast_)) {
710
862k
            desugar(ast->cond, obj_level);
711
862k
            if (ast->message == nullptr) {
712
63.6k
                ast->message = str(U"Assertion failed.");
713
63.6k
            }
714
862k
            desugar(ast->message, obj_level);
715
862k
            desugar(ast->rest, obj_level);
716
717
            // if cond then rest else error msg
718
862k
            AST *branch_false = make<Error>(ast->location, EF, ast->message);
719
862k
            ast_ = make<Conditional>(
720
862k
                ast->location, ast->openFodder, ast->cond, EF, ast->rest, EF, branch_false);
721
722
153M
        } else if (auto *ast = dynamic_cast<Binary *>(ast_)) {
723
18.5M
            desugar(ast->left, obj_level);
724
18.5M
            desugar(ast->right, obj_level);
725
726
18.5M
            bool invert = false;
727
728
18.5M
            switch (ast->op) {
729
666k
                case BOP_PERCENT: {
730
666k
                    AST *f_mod = make<Index>(
731
666k
                        E, EF, std(), EF, false, str(U"mod"), EF, nullptr, EF, nullptr, EF);
732
666k
                    ArgParams args = {{ast->left, EF}, {ast->right, EF}};
733
666k
                    ast_ = make<Apply>(
734
666k
                        ast->location, ast->openFodder, f_mod, EF, args, false, EF, EF, false);
735
666k
                } break;
736
737
515k
                case BOP_MANIFEST_UNEQUAL: invert = true;
738
515k
                [[fallthrough]];
739
3.82M
                case BOP_MANIFEST_EQUAL: {
740
3.82M
                    ast_ = equals(ast->location, ast->left, ast->right);
741
3.82M
                    if (invert)
742
515k
                        ast_ = make<Unary>(ast->location, ast->openFodder, UOP_NOT, ast_);
743
3.82M
                } break;
744
745
14.0M
                default:;
746
                    // Otherwise don't change it.
747
18.5M
            }
748
749
134M
        } else if (dynamic_cast<const BuiltinFunction *>(ast_)) {
750
            // Nothing to do.
751
752
134M
        } else if (auto *ast = dynamic_cast<Conditional *>(ast_)) {
753
6.95M
            desugar(ast->cond, obj_level);
754
6.95M
            desugar(ast->branchTrue, obj_level);
755
6.95M
            if (ast->branchFalse == nullptr)
756
84.0k
                ast->branchFalse = null();
757
6.95M
            desugar(ast->branchFalse, obj_level);
758
759
127M
        } else if (auto *ast = dynamic_cast<Dollar *>(ast_)) {
760
90.0k
            if (obj_level == 0) {
761
571
                throw StaticError(ast->location, "No top-level object found.");
762
571
            }
763
89.4k
            ast_ = var(id(U"$"));
764
765
127M
        } else if (auto *ast = dynamic_cast<Error *>(ast_)) {
766
1.41M
            desugar(ast->expr, obj_level);
767
768
126M
        } else if (auto *ast = dynamic_cast<Function *>(ast_)) {
769
517k
            desugar(ast->body, obj_level);
770
517k
            desugarParams(ast->params, obj_level);
771
772
125M
        } else if (auto *ast = dynamic_cast<Import *>(ast_)) {
773
            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
774
802
            AST *file = ast->file;
775
802
            desugar(file, obj_level);
776
802
            ast->file = dynamic_cast<LiteralString *>(file);
777
778
125M
        } else if (auto *ast = dynamic_cast<Importstr *>(ast_)) {
779
            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
780
2.42k
            AST *file = ast->file;
781
2.42k
            desugar(file, obj_level);
782
2.42k
            ast->file = dynamic_cast<LiteralString *>(file);
783
784
125M
        } else if (auto *ast = dynamic_cast<Importbin *>(ast_)) {
785
            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
786
891
            AST *file = ast->file;
787
891
            desugar(file, obj_level);
788
891
            ast->file = dynamic_cast<LiteralString *>(file);
789
790
125M
        } else if (auto *ast = dynamic_cast<InSuper *>(ast_)) {
791
20.7k
            desugar(ast->element, obj_level);
792
793
125M
        } else if (auto *ast = dynamic_cast<Index *>(ast_)) {
794
18.8M
            desugar(ast->target, obj_level);
795
18.8M
            if (ast->isSlice) {
796
387k
                if (ast->index == nullptr)
797
50.5k
                    ast->index = null();
798
387k
                desugar(ast->index, obj_level);
799
800
387k
                if (ast->end == nullptr)
801
217k
                    ast->end = null();
802
387k
                desugar(ast->end, obj_level);
803
804
387k
                if (ast->step == nullptr)
805
364k
                    ast->step = null();
806
387k
                desugar(ast->step, obj_level);
807
808
387k
                ast_ = make<Apply>(
809
387k
                    ast->location,
810
387k
                    EF,
811
387k
                    make<Index>(
812
387k
                        E, EF, std(), EF, false, str(U"slice"), EF, nullptr, EF, nullptr, EF),
813
387k
                    EF,
814
387k
                    ArgParams{
815
387k
                        {ast->target, EF},
816
387k
                        {ast->index, EF},
817
387k
                        {ast->end, EF},
818
387k
                        {ast->step, EF},
819
387k
                    },
820
387k
                    false,  // trailing comma
821
387k
                    EF,
822
387k
                    EF,
823
387k
                    false  // tailstrict
824
387k
                );
825
18.4M
            } else {
826
18.4M
                if (ast->id != nullptr) {
827
15.0M
                    assert(ast->index == nullptr);
828
15.0M
                    ast->index = str(ast->id->name);
829
15.0M
                    ast->id = nullptr;
830
15.0M
                }
831
18.4M
                desugar(ast->index, obj_level);
832
18.4M
            }
833
834
107M
        } else if (auto *ast = dynamic_cast<Local *>(ast_)) {
835
5.16M
            for (auto &bind : ast->binds)
836
5.49M
                desugar(bind.body, obj_level);
837
5.16M
            desugar(ast->body, obj_level);
838
839
5.49M
            for (auto &bind : ast->binds) {
840
5.49M
                if (bind.functionSugar) {
841
1.55M
                    desugarParams(bind.params, obj_level);
842
1.55M
                    bind.body = make<Function>(ast->location,
843
1.55M
                                               ast->openFodder,
844
1.55M
                                               bind.parenLeftFodder,
845
1.55M
                                               bind.params,
846
1.55M
                                               false,
847
1.55M
                                               bind.parenRightFodder,
848
1.55M
                                               bind.body);
849
1.55M
                    bind.functionSugar = false;
850
1.55M
                    bind.params.clear();
851
1.55M
                }
852
5.49M
            }
853
854
101M
        } else if (dynamic_cast<const LiteralBoolean *>(ast_)) {
855
            // Nothing to do.
856
857
100M
        } else if (dynamic_cast<const LiteralNumber *>(ast_)) {
858
            // Nothing to do.
859
860
89.0M
        } else if (auto *ast = dynamic_cast<LiteralString *>(ast_)) {
861
25.7M
            if ((ast->tokenKind != LiteralString::RAW_DESUGARED) &&
862
10.1M
                (ast->tokenKind != LiteralString::BLOCK) &&
863
10.1M
                (ast->tokenKind != LiteralString::VERBATIM_DOUBLE) &&
864
10.1M
                (ast->tokenKind != LiteralString::VERBATIM_SINGLE)) {
865
10.1M
                ast->value = jsonnet_string_unescape(ast->location, ast->value);
866
10.1M
            }
867
25.7M
            ast->tokenKind = LiteralString::RAW_DESUGARED;
868
25.7M
            ast->blockIndent.clear();
869
870
63.3M
        } else if (dynamic_cast<const LiteralNull *>(ast_)) {
871
            // Nothing to do.
872
873
62.2M
        } else if (auto *ast = dynamic_cast<DesugaredObject *>(ast_)) {
874
178k
            for (auto &field : ast->fields) {
875
140k
                desugar(field.name, obj_level);
876
140k
                desugar(field.body, obj_level + 1);
877
140k
            }
878
178k
            for (AST *assert : ast->asserts) {
879
4.07k
                desugar(assert, obj_level + 1);
880
4.07k
            }
881
882
62.0M
        } else if (auto *ast = dynamic_cast<Object *>(ast_)) {
883
1.13M
            ast_ = makeObject(ast, obj_level);
884
885
60.9M
        } else if (auto *ast = dynamic_cast<ObjectComprehension *>(ast_)) {
886
92.9k
            ast_ = makeObjectComprehension(ast, obj_level);
887
888
60.8M
        } else if (auto *ast = dynamic_cast<ObjectComprehensionSimple *>(ast_)) {
889
23.1k
            desugar(ast->field, obj_level);
890
23.1k
            desugar(ast->value, obj_level + 1);
891
23.1k
            desugar(ast->array, obj_level);
892
893
60.8M
        } else if (auto *ast = dynamic_cast<Parens *>(ast_)) {
894
            // Strip parens.
895
1.05M
            desugar(ast->expr, obj_level);
896
1.05M
            ast_ = ast->expr;
897
898
59.7M
        } else if (dynamic_cast<const Self *>(ast_)) {
899
            // Nothing to do.
900
901
59.5M
        } else if (auto *ast = dynamic_cast<SuperIndex *>(ast_)) {
902
24.4k
            if (ast->id != nullptr) {
903
3.88k
                assert(ast->index == nullptr);
904
3.88k
                ast->index = str(ast->id->name);
905
3.88k
                ast->id = nullptr;
906
3.88k
            }
907
24.4k
            desugar(ast->index, obj_level);
908
909
59.5M
        } else if (auto *ast = dynamic_cast<Unary *>(ast_)) {
910
1.99M
            desugar(ast->expr, obj_level);
911
912
57.5M
        } else if (dynamic_cast<const Var *>(ast_)) {
913
            // Nothing to do.
914
915
57.5M
        } else {
916
0
            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
917
0
            std::abort();
918
0
        }
919
174M
    }
920
921
21.0k
    DesugaredObject *stdlibAST(std::string filename) {
922
        // Now, implement the std library by wrapping in a local construct.
923
21.0k
        Tokens tokens = jsonnet_lex("std.jsonnet", STD_CODE);
924
21.0k
        AST *std_ast = jsonnet_parse(alloc, tokens);
925
21.0k
        desugar(std_ast, 0);
926
21.0k
        auto *std_obj = dynamic_cast<DesugaredObject *>(std_ast);
927
21.0k
        if (std_obj == nullptr) {
928
0
            std::cerr << "INTERNAL ERROR: std.jsonnet not an object." << std::endl;
929
0
            std::abort();
930
0
        }
931
932
        // Bind 'std' builtins that are implemented natively.
933
21.0k
        DesugaredObject::Fields &fields = std_obj->fields;
934
903k
        for (unsigned long c = 0; c <= max_builtin; ++c) {
935
882k
            const auto &decl = jsonnet_builtin_decl(c);
936
882k
            Identifiers params;
937
882k
            for (const auto &p : decl.params)
938
1.30M
                params.push_back(id(p));
939
882k
            auto name = str(decl.name);
940
882k
            auto fn = make<BuiltinFunction>(E, encode_utf8(decl.name), params);
941
882k
            auto field = std::find_if(fields.begin(), fields.end(),
942
107M
                [=](const DesugaredObject::Field& f) {
943
107M
                    return static_cast<LiteralString*>(f.name)->value == decl.name;
944
107M
                });
945
882k
            if (field != fields.end()) {
946
147k
                field->body = fn;
947
735k
            } else {
948
735k
                fields.emplace_back(ObjectField::HIDDEN, name, fn);
949
735k
            }
950
882k
        }
951
21.0k
        fields.emplace_back(
952
21.0k
            ObjectField::HIDDEN, str(U"thisFile"), str(decode_utf8(filename)));
953
21.0k
        return std_obj;
954
21.0k
    }
955
956
    void desugarFile(AST *&ast, std::map<std::string, VmExt> *tlas)
957
12.6k
    {
958
12.6k
        desugar(ast, 0);
959
960
12.6k
        DesugaredObject *std_obj = stdlibAST(ast->location.file);
961
962
12.6k
        std::vector<std::string> empty;
963
12.6k
        auto line_end_blank = Fodder{{FodderElement::LINE_END, 1, 0, empty}};
964
12.6k
        auto line_end = Fodder{{FodderElement::LINE_END, 0, 0, empty}};
965
966
        // local body = ast;
967
        // if std.type(body) == "function") then
968
        //     body(tlas...)
969
        // else
970
        //     body
971
12.6k
        if (tlas != nullptr) {
972
11.4k
            LocationRange tla_loc("Top-level function");
973
11.4k
            ArgParams args;
974
11.4k
            for (const auto &pair : *tlas) {
975
0
                AST *expr;
976
0
                if (pair.second.isCode) {
977
0
                    Tokens tokens = jsonnet_lex("tla:" + pair.first, pair.second.data.c_str());
978
0
                    expr = jsonnet_parse(alloc, tokens);
979
0
                    desugar(expr, 0);
980
0
                } else {
981
0
                    expr = str(decode_utf8(pair.second.data));
982
0
                }
983
                // Add them as named arguments, so order does not matter.
984
0
                args.emplace_back(EF, id(decode_utf8(pair.first)), EF, expr, EF);
985
0
            }
986
11.4k
            const Identifier *body = id(U"top_level");
987
11.4k
            ast =
988
11.4k
                make<Local>(ast->location,
989
11.4k
                            line_end_blank,
990
11.4k
                            singleBind(body, ast),
991
11.4k
                            make<Conditional>(E,
992
11.4k
                                              line_end,
993
11.4k
                                              primitiveEquals(E, type(var(body)), str(U"function")),
994
11.4k
                                              EF,
995
11.4k
                                              make<Apply>(tla_loc,
996
11.4k
                                                          EF,
997
11.4k
                                                          make<Var>(E, line_end, body),
998
11.4k
                                                          EF,
999
11.4k
                                                          args,
1000
11.4k
                                                          false,  // trailing comma
1001
11.4k
                                                          EF,
1002
11.4k
                                                          EF,
1003
11.4k
                                                          false  // tailstrict
1004
11.4k
                                                          ),
1005
11.4k
                                              line_end,
1006
11.4k
                                              make<Var>(E, line_end, body)));
1007
11.4k
        }
1008
1009
        // local $std = (std.jsonnet stuff); std = $std; ast
1010
        // The standard library is bound to $std, which cannot be overriden,
1011
        // so redefining std won't break expressions that desugar to calls
1012
        // to standard library functions.
1013
12.6k
        ast = make<Local>(ast->location, EF, singleBind(id(U"std"), std()), ast);
1014
12.6k
        ast = make<Local>(ast->location, EF, singleBind(id(U"$std"), std_obj), ast);
1015
12.6k
    }
1016
};
1017
1018
9.56k
DesugaredObject *makeStdlibAST(Allocator *alloc, std::string filename) {
1019
9.56k
    Desugarer desugarer(alloc, true);
1020
9.56k
    return desugarer.stdlibAST(filename);
1021
9.56k
}
1022
1023
void jsonnet_desugar(Allocator *alloc, AST *&ast, std::map<std::string, VmExt> *tlas)
1024
12.6k
{
1025
12.6k
    Desugarer desugarer(alloc);
1026
12.6k
    desugarer.desugarFile(ast, tlas);
1027
12.6k
}
1028
1029
}  // namespace jsonnet::internal