Coverage Report

Created: 2026-11-12 07:16

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
937k
{
42
937k
    switch (builtin) {
43
22.3k
        case 0: return {U"makeArray", {U"sz", U"func"}};
44
22.3k
        case 1: return {U"pow", {U"x", U"n"}};
45
22.3k
        case 2: return {U"floor", {U"x"}};
46
22.3k
        case 3: return {U"ceil", {U"x"}};
47
22.3k
        case 4: return {U"sqrt", {U"x"}};
48
22.3k
        case 5: return {U"sin", {U"x"}};
49
22.3k
        case 6: return {U"cos", {U"x"}};
50
22.3k
        case 7: return {U"tan", {U"x"}};
51
22.3k
        case 8: return {U"asin", {U"x"}};
52
22.3k
        case 9: return {U"acos", {U"x"}};
53
22.3k
        case 10: return {U"atan", {U"x"}};
54
22.3k
        case 11: return {U"type", {U"x"}};
55
22.3k
        case 12: return {U"filter", {U"func", U"arr"}};
56
22.3k
        case 13: return {U"objectHasEx", {U"obj", U"f", U"inc_hidden"}};
57
22.3k
        case 14: return {U"length", {U"x"}};
58
22.3k
        case 15: return {U"objectFieldsEx", {U"obj", U"inc_hidden"}};
59
22.3k
        case 16: return {U"codepoint", {U"str"}};
60
22.3k
        case 17: return {U"char", {U"n"}};
61
22.3k
        case 18: return {U"log", {U"n"}};
62
22.3k
        case 19: return {U"exp", {U"n"}};
63
22.3k
        case 20: return {U"mantissa", {U"n"}};
64
22.3k
        case 21: return {U"exponent", {U"n"}};
65
22.3k
        case 22: return {U"modulo", {U"a", U"b"}};
66
22.3k
        case 23: return {U"extVar", {U"x"}};
67
22.3k
        case 24: return {U"primitiveEquals", {U"a", U"b"}};
68
22.3k
        case 25: return {U"native", {U"name"}};
69
22.3k
        case 26: return {U"md5", {U"str"}};
70
22.3k
        case 27: return {U"trace", {U"str", U"rest"}};
71
22.3k
        case 28: return {U"splitLimit", {U"str", U"c", U"maxsplits"}};
72
22.3k
        case 29: return {U"substr", {U"str", U"from", U"len"}};
73
22.3k
        case 30: return {U"range", {U"from", U"to"}};
74
22.3k
        case 31: return {U"strReplace", {U"str", U"from", U"to"}};
75
22.3k
        case 32: return {U"asciiLower", {U"str"}};
76
22.3k
        case 33: return {U"asciiUpper", {U"str"}};
77
22.3k
        case 34: return {U"join", {U"sep", U"arr"}};
78
22.3k
        case 35: return {U"parseJson", {U"str"}};
79
22.3k
        case 36: return {U"parseYaml", {U"str"}};
80
22.3k
        case 37: return {U"encodeUTF8", {U"str"}};
81
22.3k
        case 38: return {U"decodeUTF8", {U"arr"}};
82
22.3k
        case 39: return {U"atan2", {U"y", U"x"}};
83
22.3k
        case 40: return {U"hypot", {U"a", U"b"}};
84
22.3k
        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
937k
    }
89
    // Quiet, compiler.
90
0
    return BuiltinDecl();
91
937k
}
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
95.8M
    {
111
95.8M
        return alloc->make<T>(std::forward<Args>(args)...);
112
95.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
213k
    {
111
213k
        return alloc->make<T>(std::forward<Args>(args)...);
112
213k
    }
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.72M
    {
111
1.72M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.72M
    }
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
811k
    {
111
811k
        return alloc->make<T>(std::forward<Args>(args)...);
112
811k
    }
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.32M
    {
111
1.32M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.32M
    }
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
811k
    {
111
811k
        return alloc->make<T>(std::forward<Args>(args)...);
112
811k
    }
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
811k
    {
111
811k
        return alloc->make<T>(std::forward<Args>(args)...);
112
811k
    }
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.40M
    {
111
1.40M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.40M
    }
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
440k
    {
111
440k
        return alloc->make<T>(std::forward<Args>(args)...);
112
440k
    }
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
887k
    {
111
887k
        return alloc->make<T>(std::forward<Args>(args)...);
112
887k
    }
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
887k
    {
111
887k
        return alloc->make<T>(std::forward<Args>(args)...);
112
887k
    }
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
887k
    {
111
887k
        return alloc->make<T>(std::forward<Args>(args)...);
112
887k
    }
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
887k
    {
111
887k
        return alloc->make<T>(std::forward<Args>(args)...);
112
887k
    }
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
911k
    {
111
911k
        return alloc->make<T>(std::forward<Args>(args)...);
112
911k
    }
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
887k
    {
111
887k
        return alloc->make<T>(std::forward<Args>(args)...);
112
887k
    }
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
887k
    {
111
887k
        return alloc->make<T>(std::forward<Args>(args)...);
112
887k
    }
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
811k
    {
111
811k
        return alloc->make<T>(std::forward<Args>(args)...);
112
811k
    }
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
31.8M
    {
111
31.8M
        return alloc->make<T>(std::forward<Args>(args)...);
112
31.8M
    }
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
2.00M
    {
111
2.00M
        return alloc->make<T>(std::forward<Args>(args)...);
112
2.00M
    }
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
915k
    {
111
915k
        return alloc->make<T>(std::forward<Args>(args)...);
112
915k
    }
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.85M
    {
111
7.85M
        return alloc->make<T>(std::forward<Args>(args)...);
112
7.85M
    }
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
689k
    {
111
689k
        return alloc->make<T>(std::forward<Args>(args)...);
112
689k
    }
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.97M
    {
111
4.97M
        return alloc->make<T>(std::forward<Args>(args)...);
112
4.97M
    }
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
548k
    {
111
548k
        return alloc->make<T>(std::forward<Args>(args)...);
112
548k
    }
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
757k
    {
111
757k
        return alloc->make<T>(std::forward<Args>(args)...);
112
757k
    }
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
18.4M
    {
111
18.4M
        return alloc->make<T>(std::forward<Args>(args)...);
112
18.4M
    }
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.19M
    {
111
2.19M
        return alloc->make<T>(std::forward<Args>(args)...);
112
2.19M
    }
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.65M
    {
111
1.65M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.65M
    }
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
74.9k
    {
111
74.9k
        return alloc->make<T>(std::forward<Args>(args)...);
112
74.9k
    }
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
203k
    {
111
203k
        return alloc->make<T>(std::forward<Args>(args)...);
112
203k
    }
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
203k
    {
111
203k
        return alloc->make<T>(std::forward<Args>(args)...);
112
203k
    }
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.80M
    {
111
2.80M
        return alloc->make<T>(std::forward<Args>(args)...);
112
2.80M
    }
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
39.1k
    {
111
39.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
39.1k
    }
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
39.1k
    {
111
39.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
39.1k
    }
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
39.1k
    {
111
39.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
39.1k
    }
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
39.1k
    {
111
39.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
39.1k
    }
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.18M
    {
111
1.18M
        return alloc->make<T>(std::forward<Args>(args)...);
112
1.18M
    }
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
3.14M
    {
111
3.14M
        return alloc->make<T>(std::forward<Args>(args)...);
112
3.14M
    }
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
97.1k
    {
111
97.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
97.1k
    }
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
97.1k
    {
111
97.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
97.1k
    }
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
97.1k
    {
111
97.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
97.1k
    }
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
97.1k
    {
111
97.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
97.1k
    }
jsonnet::internal::BuiltinFunction* jsonnet::internal::Desugarer::make<jsonnet::internal::BuiltinFunction, jsonnet::internal::LocationRange const&, jsonnet::internal::BuiltinFunctionBody const*&>(jsonnet::internal::LocationRange const&, jsonnet::internal::BuiltinFunctionBody const*&)
Line
Count
Source
110
937k
    {
111
937k
        return alloc->make<T>(std::forward<Args>(args)...);
112
937k
    }
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
12.1k
    {
111
12.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
12.1k
    }
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
12.1k
    {
111
12.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
12.1k
    }
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
12.1k
    {
111
12.1k
        return alloc->make<T>(std::forward<Args>(args)...);
112
12.1k
    }
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
24.2k
    {
111
24.2k
        return alloc->make<T>(std::forward<Args>(args)...);
112
24.2k
    }
113
114
    AST *clone(AST *ast)
115
117k
    {
116
117k
        return clone_ast(*alloc, ast);
117
117k
    }
118
119
    const Identifier *id(const UString &s)
120
13.9M
    {
121
13.9M
        return alloc->makeIdentifier(s);
122
13.9M
    }
123
124
    LiteralString *str(const UString &s)
125
25.8M
    {
126
25.8M
        return make<LiteralString>(E, EF, s, LiteralString::RAW_DESUGARED, "", "");
127
25.8M
    }
128
129
    LiteralString *str(const LocationRange &loc, const UString &s)
130
5.98M
    {
131
5.98M
        return make<LiteralString>(loc, EF, s, LiteralString::RAW_DESUGARED, "", "");
132
5.98M
    }
133
134
    LiteralNull *null(void)
135
757k
    {
136
757k
        return make<LiteralNull>(E, EF);
137
757k
    }
138
139
    Var *var(const Identifier *ident)
140
18.4M
    {
141
18.4M
        return make<Var>(E, EF, ident);
142
18.4M
    }
143
144
    Var *std(void)
145
7.87M
    {
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.87M
        return var(id(isStdlib ? U"std" : U"$std"));
150
7.87M
    }
151
152
    Local::Bind bind(const Identifier *id, AST *body)
153
3.72M
    {
154
3.72M
        return Local::Bind(EF, id, EF, body, false, EF, ArgParams{}, false, EF, EF);
155
3.72M
    }
156
157
    Local::Binds singleBind(const Identifier *id, AST *body)
158
923k
    {
159
923k
        return {bind(id, body)};
160
923k
    }
161
162
    Array *singleton(AST *body)
163
811k
    {
164
811k
        return make<Array>(
165
811k
            body->location, EF, Array::Elements{Array::Element(body, EF)}, false, EF);
166
811k
    }
167
168
    Apply *stdFunc(const UString &name, AST *v)
169
1.78M
    {
170
1.78M
        return make<Apply>(
171
1.78M
            v->location,
172
1.78M
            EF,
173
1.78M
            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
174
1.78M
            EF,
175
1.78M
            ArgParams{{v, EF}},
176
1.78M
            false,  // trailingComma
177
1.78M
            EF,
178
1.78M
            EF,
179
1.78M
            true  // tailstrict
180
1.78M
        );
181
1.78M
    }
182
183
    Apply *stdFunc(const LocationRange &loc, const UString &name, AST *a, AST *b)
184
4.97M
    {
185
4.97M
        return make<Apply>(
186
4.97M
            loc,
187
4.97M
            EF,
188
4.97M
            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
189
4.97M
            EF,
190
4.97M
            ArgParams{{a, EF}, {b, EF}},
191
4.97M
            false,  // trailingComma
192
4.97M
            EF,
193
4.97M
            EF,
194
4.97M
            true  // tailstrict
195
4.97M
        );
196
4.97M
    }
197
198
    Apply *length(AST *v)
199
887k
    {
200
887k
        return stdFunc(U"length", v);
201
887k
    }
202
203
    Apply *type(AST *v)
204
899k
    {
205
899k
        return stdFunc(U"type", v);
206
899k
    }
207
208
    Apply *primitiveEquals(const LocationRange &loc, AST *a, AST *b)
209
12.1k
    {
210
12.1k
        return stdFunc(loc, U"primitiveEquals", a, b);
211
12.1k
    }
212
213
    Apply *equals(const LocationRange &loc, AST *a, AST *b)
214
4.95M
    {
215
4.95M
        return stdFunc(loc, U"equals", a, b);
216
4.95M
    }
217
218
    Error *error(AST *msg)
219
1.09M
    {
220
1.09M
        return make<Error>(msg->location, EF, msg);
221
1.09M
    }
222
223
    Error *error(const LocationRange &loc, const UString &msg)
224
887k
    {
225
887k
        return error(str(loc, msg));
226
887k
    }
227
228
   public:
229
23.6k
    Desugarer(Allocator *alloc, bool isStdlib = false) : alloc(alloc), isStdlib(isStdlib) {}
230
231
    void desugarParams(ArgParams &params, unsigned obj_level)
232
7.99M
    {
233
9.88M
        for (auto &param : params) {
234
9.88M
            if (param.expr) {
235
                // Default arg.
236
477k
                desugar(param.expr, obj_level);
237
477k
            }
238
9.88M
        }
239
7.99M
    }
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.28M
    {
247
        // Desugar children
248
5.79M
        for (auto &field : fields) {
249
5.79M
            if (field.expr1 != nullptr)
250
317k
                desugar(field.expr1, obj_level);
251
5.79M
            desugar(field.expr2, obj_level + 1);
252
5.79M
            if (field.expr3 != nullptr)
253
149k
                desugar(field.expr3, obj_level + 1);
254
5.79M
            desugarParams(field.params, obj_level + 1);
255
5.79M
        }
256
257
        // Simplify asserts
258
5.79M
        for (auto &field : fields) {
259
5.79M
            if (field.kind != ObjectField::ASSERT)
260
5.59M
                continue;
261
203k
            AST *msg = field.expr3;
262
203k
            field.expr3 = nullptr;
263
203k
            if (msg == nullptr) {
264
                // The location is what appears in the stacktrace.
265
53.3k
                msg = str(field.expr2->location, U"Object assertion failed.");
266
53.3k
            }
267
268
            // if expr2 then true else error msg
269
203k
            field.expr2 = make<Conditional>(field.expr2->location,
270
203k
                                            EF,
271
203k
                                            field.expr2,
272
203k
                                            EF,
273
203k
                                            make<LiteralBoolean>(E, EF, true),
274
203k
                                            EF,
275
203k
                                            error(msg));
276
203k
        }
277
278
        // Remove methods
279
5.79M
        for (auto &field : fields) {
280
5.79M
            if (!field.methodSugar)
281
2.98M
                continue;
282
2.80M
            field.expr2 = make<Function>(field.expr2->location,
283
2.80M
                                         EF,
284
2.80M
                                         field.fodderL,
285
2.80M
                                         field.params,
286
2.80M
                                         field.trailingComma,
287
2.80M
                                         field.fodderR,
288
2.80M
                                         field.expr2);
289
2.80M
            field.methodSugar = false;
290
2.80M
            field.params.clear();
291
2.80M
        }
292
293
        // Remove object-level locals
294
1.28M
        auto copy = fields;
295
1.28M
        fields.clear();
296
1.28M
        Local::Binds binds;
297
5.79M
        for (auto &local : copy) {
298
5.79M
            if (local.kind != ObjectField::LOCAL)
299
5.56M
                continue;
300
229k
            binds.push_back(bind(local.id, local.expr2));
301
229k
        }
302
5.79M
        for (auto &field : copy) {
303
5.79M
            if (field.kind == ObjectField::LOCAL)
304
229k
                continue;
305
5.56M
            if (!binds.empty())
306
3.04M
                field.expr2 = make<Local>(field.expr2->location, EF, binds, field.expr2);
307
5.56M
            fields.push_back(field);
308
5.56M
        }
309
310
        // Change all to FIELD_EXPR
311
5.56M
        for (auto &field : fields) {
312
5.56M
            switch (field.kind) {
313
203k
                case ObjectField::ASSERT:
314
                    // Nothing to do.
315
203k
                    break;
316
317
5.04M
                case ObjectField::FIELD_ID:
318
5.04M
                    field.expr1 = str(field.idLocation, field.id->name);
319
5.04M
                    field.kind = ObjectField::FIELD_EXPR;
320
5.04M
                    break;
321
322
105k
                case ObjectField::FIELD_EXPR:
323
                    // Nothing to do.
324
105k
                    break;
325
326
212k
                case ObjectField::FIELD_STR:
327
                    // Just set the flag.
328
212k
                    field.kind = ObjectField::FIELD_EXPR;
329
212k
                    break;
330
331
0
                case ObjectField::LOCAL:
332
0
                    std::cerr << "Locals should be removed by now." << std::endl;
333
0
                    abort();
334
5.56M
            }
335
5.56M
        }
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.28M
        class SubstituteSelfSuper : public CompilerPass {
342
1.28M
            Desugarer *desugarer;
343
1.28M
            SuperVars &superVars;
344
1.28M
            unsigned &counter;
345
1.28M
            const Identifier *newSelf;
346
347
1.28M
           public:
348
1.28M
            SubstituteSelfSuper(Desugarer *desugarer, SuperVars &super_vars, unsigned &counter)
349
1.28M
                : CompilerPass(*desugarer->alloc),
350
1.28M
                  desugarer(desugarer),
351
1.28M
                  superVars(super_vars),
352
1.28M
                  counter(counter),
353
1.28M
                  newSelf(nullptr)
354
1.28M
            {
355
39.1k
            }
356
1.28M
            void visitExpr(AST *&expr)
357
3.36M
            {
358
3.36M
                if (dynamic_cast<Self *>(expr)) {
359
12.2k
                    if (newSelf == nullptr) {
360
2.38k
                        newSelf = desugarer->id(U"$outer_self");
361
2.38k
                        superVars.emplace_back(newSelf, nullptr);
362
2.38k
                    }
363
12.2k
                    expr = alloc.make<Var>(expr->location, expr->openFodder, newSelf);
364
3.35M
                } else if (auto *super_index = dynamic_cast<SuperIndex *>(expr)) {
365
380k
                    UStringStream ss;
366
380k
                    ss << U"$outer_super_index" << (counter++);
367
380k
                    const Identifier *super_var = desugarer->id(ss.str());
368
                    // Desugaring of expr should already have occurred.
369
380k
                    assert(super_index->index != nullptr);
370
                    // Re-use super_index since we're replacing it here.
371
380k
                    superVars.emplace_back(super_var, super_index);
372
380k
                    expr = alloc.make<Var>(expr->location, expr->openFodder, super_var);
373
2.97M
                } else if (auto *in_super = dynamic_cast<InSuper *>(expr)) {
374
357k
                    UStringStream ss;
375
357k
                    ss << U"$outer_in_super" << (counter++);
376
357k
                    const Identifier *in_super_var = desugarer->id(ss.str());
377
                    // Re-use in_super since we're replacing it here.
378
357k
                    superVars.emplace_back(in_super_var, in_super);
379
357k
                    expr = alloc.make<Var>(expr->location, expr->openFodder, in_super_var);
380
357k
                }
381
3.36M
                CompilerPass::visitExpr(expr);
382
3.36M
            }
383
1.28M
        };
384
385
1.28M
        SuperVars super_vars;
386
1.28M
        unsigned counter = 0;
387
388
        // Remove +:
389
5.56M
        for (auto &field : fields) {
390
5.56M
            if (!field.superSugar)
391
5.52M
                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
39.1k
            AST *index = clone(field.expr1);
396
            // This will remove self/super.
397
39.1k
            SubstituteSelfSuper(this, super_vars, counter).expr(index);
398
39.1k
            field.expr2 = make<Conditional>(
399
39.1k
                ast->location,
400
39.1k
                EF,
401
39.1k
                make<InSuper>(ast->location, EF, index, EF, EF),
402
39.1k
                EF,
403
39.1k
                make<Binary>(ast->location,
404
39.1k
                             EF,
405
39.1k
                             make<SuperIndex>(ast->location, EF, EF, clone(index), EF, nullptr),
406
39.1k
                             EF,
407
39.1k
                             BOP_PLUS,
408
39.1k
                             field.expr2),
409
39.1k
                EF,
410
39.1k
                clone(field.expr2));
411
39.1k
            field.superSugar = false;
412
39.1k
        }
413
414
1.28M
        return super_vars;
415
1.28M
    }
416
417
811k
    AST* makeArrayComprehension(ArrayComprehension *ast) {
418
811k
        int n = ast->specs.size();
419
811k
        AST *zero = make<LiteralNumber>(E, EF, "0.0");
420
811k
        AST *one = make<LiteralNumber>(E, EF, "1.0");
421
811k
        auto *_r = id(U"$r");
422
811k
        auto *_l = id(U"$l");
423
811k
        std::vector<const Identifier *> _i(n);
424
2.13M
        for (int i = 0; i < n; ++i) {
425
1.32M
            UStringStream ss;
426
1.32M
            ss << U"$i_" << i;
427
1.32M
            _i[i] = id(ss.str());
428
1.32M
        }
429
811k
        std::vector<const Identifier *> _aux(n);
430
2.13M
        for (int i = 0; i < n; ++i) {
431
1.32M
            UStringStream ss;
432
1.32M
            ss << U"$aux_" << i;
433
1.32M
            _aux[i] = id(ss.str());
434
1.32M
        }
435
436
        // Build it from the inside out.  We keep wrapping 'in' with more ASTs.
437
811k
        assert(ast->specs[0].kind == ComprehensionSpec::FOR);
438
439
811k
        int last_for = n - 1;
440
1.24M
        while (ast->specs[last_for].kind != ComprehensionSpec::FOR)
441
435k
            last_for--;
442
        // $aux_{last_for}($i_{last_for} + 1, $r + [body])
443
811k
        AST *in = make<Apply>(
444
811k
            ast->body->location,
445
811k
            EF,
446
811k
            var(_aux[last_for]),
447
811k
            EF,
448
811k
            ArgParams{{make<Binary>(E, EF, var(_i[last_for]), EF, BOP_PLUS, one), EF},
449
811k
                {make<Binary>(E, EF, var(_r), EF, BOP_PLUS, singleton(ast->body)), EF}},
450
811k
            false,  // trailingComma
451
811k
            EF,
452
811k
            EF,
453
811k
            true  // tailstrict
454
811k
        );
455
2.13M
        for (int i = n - 1; i >= 0; --i) {
456
1.32M
            const ComprehensionSpec &spec = ast->specs[i];
457
1.32M
            AST *out;
458
1.32M
            if (i > 0) {
459
516k
                int prev_for = i - 1;
460
2.36G
                while (ast->specs[prev_for].kind != ComprehensionSpec::FOR)
461
2.36G
                    prev_for--;
462
463
                // aux_{prev_for}($i_{prev_for} + 1, $r)
464
516k
                out = make<Apply>(  // False branch.
465
516k
                    E,
466
516k
                    EF,
467
516k
                    var(_aux[prev_for]),
468
516k
                    EF,
469
516k
                    ArgParams{{
470
516k
                        make<Binary>(E, EF, var(_i[prev_for]), EF, BOP_PLUS, one),
471
516k
                            EF,
472
516k
                            },
473
516k
                      {
474
516k
                        var(_r),
475
516k
                            EF,
476
516k
                            }},
477
516k
                    false,  // trailingComma
478
516k
                    EF,
479
516k
                    EF,
480
516k
                    true  // tailstrict
481
516k
                );
482
811k
            } else {
483
811k
                out = var(_r);
484
811k
            }
485
1.32M
            switch (spec.kind) {
486
440k
                case ComprehensionSpec::IF: {
487
                  /*
488
                    if [[[...cond...]]] then
489
                    [[[...in...]]]
490
                    else
491
                    [[[...out...]]]
492
                  */
493
440k
                    in = make<Conditional>(ast->location,
494
440k
                                           EF,
495
440k
                                           spec.expr,
496
440k
                                           EF,
497
440k
                                           in,  // True branch.
498
440k
                                           EF,
499
440k
                                           out);  // False branch.
500
440k
                } break;
501
887k
                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
887k
                    in = make<Local>(
516
887k
                        ast->location,
517
887k
                        EF,
518
887k
                        Local::Binds{
519
887k
                          bind(_l, spec.expr),  // Need to check expr is an array
520
887k
                              bind(_aux[i],
521
887k
                                   make<Function>(
522
887k
                                       ast->location,
523
887k
                                       EF,
524
887k
                                       EF,
525
887k
                                       ArgParams{{EF, _i[i], EF}, {EF, _r, EF}},
526
887k
                                       false,  // trailingComma
527
887k
                                       EF,
528
887k
                                       make<Conditional>(ast->location,
529
887k
                                                         EF,
530
887k
                                                         make<Binary>(E,
531
887k
                                                                      EF,
532
887k
                                                                      var(_i[i]),
533
887k
                                                                      EF,
534
887k
                                                                      BOP_GREATER_EQ,
535
887k
                                                                      length(var(_l))),
536
887k
                                                         EF,
537
887k
                                                         out,
538
887k
                                                         EF,
539
887k
                                                         make<Local>(
540
887k
                                                             ast->location,
541
887k
                                                             EF,
542
887k
                                                             singleBind(spec.var,
543
887k
                                                                        make<Index>(E,
544
887k
                                                                                    EF,
545
887k
                                                                                    var(_l),
546
887k
                                                                                    EF,
547
887k
                                                                                    false,
548
887k
                                                                                    var(_i[i]),
549
887k
                                                                                    EF,
550
887k
                                                                                    nullptr,
551
887k
                                                                                    EF,
552
887k
                                                                                    nullptr,
553
887k
                                                                                    EF)),
554
887k
                                                             in))))},
555
887k
                        make<Conditional>(
556
887k
                            ast->location,
557
887k
                            EF,
558
887k
                            equals(ast->location, type(var(_l)), str(U"array")),
559
887k
                            EF,
560
887k
                            make<Apply>(
561
887k
                                E,
562
887k
                                EF,
563
887k
                                var(_aux[i]),
564
887k
                                EF,
565
887k
                                ArgParams{{zero, EF},
566
887k
                                  {
567
887k
                                    i == 0 ? make<Array>(
568
811k
                                        E, EF, Array::Elements{}, false, EF)
569
887k
                                        : static_cast<AST *>(var(_r)),
570
887k
                                        EF,
571
887k
                                        }},
572
887k
                                false,  // trailingComma
573
887k
                                EF,
574
887k
                                EF,
575
887k
                                true),  // tailstrict
576
887k
                            EF,
577
887k
                            error(ast->location,
578
887k
                                  U"In comprehension, can only iterate over array.")));
579
887k
                } break;
580
1.32M
            }
581
1.32M
        }
582
583
811k
        return in;
584
811k
    }
585
586
1.18M
    AST* makeObject(Object *ast, unsigned obj_level) {
587
        // Hidden variable to allow outer/top binding.
588
1.18M
        if (obj_level == 0) {
589
71.3k
            const Identifier *hidden_var = id(U"$");
590
71.3k
            auto *body = make<Self>(E, EF);
591
71.3k
            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
592
71.3k
        }
593
594
1.18M
        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
595
596
1.18M
        DesugaredObject::Fields new_fields;
597
1.18M
        ASTs new_asserts;
598
5.47M
        for (const ObjectField &field : ast->fields) {
599
5.47M
            if (field.kind == ObjectField::ASSERT) {
600
203k
                new_asserts.push_back(field.expr2);
601
5.26M
            } else if (field.kind == ObjectField::FIELD_EXPR) {
602
5.26M
                new_fields.emplace_back(field.hide, field.expr1, field.expr2);
603
5.26M
            } else {
604
0
                std::cerr << "INTERNAL ERROR: field should have been desugared: " << field.kind
605
0
                          << std::endl;
606
0
            }
607
5.47M
        }
608
609
1.18M
        AST* retval = make<DesugaredObject>(ast->location, new_asserts, new_fields);
610
1.18M
        if (svs.size() > 0) {
611
4.56k
            Local::Binds binds;
612
696k
            for (const auto &pair : svs) {
613
696k
                if (pair.second == nullptr) {
614
                    // Self binding
615
1.78k
                    binds.push_back(bind(pair.first, make<Self>(E, EF)));
616
695k
                } else {
617
                    // Super binding
618
695k
                    binds.push_back(bind(pair.first, pair.second));
619
695k
                }
620
696k
            }
621
4.56k
            retval = make<Local>(ast->location, EF, binds, retval);
622
4.56k
        }
623
624
1.18M
        return retval;
625
1.18M
    }
626
627
97.1k
    AST* makeObjectComprehension(ObjectComprehension *ast, unsigned obj_level) {
628
        // Hidden variable to allow outer/top binding.
629
97.1k
        if (obj_level == 0) {
630
1.85k
            const Identifier *hidden_var = id(U"$");
631
1.85k
            auto *body = make<Self>(E, EF);
632
1.85k
            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
633
1.85k
        }
634
635
97.1k
        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
636
637
97.1k
        AST *field = ast->fields.front().expr1;
638
97.1k
        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
97.1k
        auto *_arr = id(U"$arr");
646
97.1k
        AST *zero = make<LiteralNumber>(E, EF, "0.0");
647
97.1k
        int counter = 1;
648
97.1k
        Local::Binds binds;
649
97.1k
        Array::Elements arr_e{Array::Element(field, EF)};
650
136k
        for (ComprehensionSpec &spec : ast->specs) {
651
136k
            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
136k
        }
669
97.1k
        AST *arr = make<ArrayComprehension>(ast->location,
670
97.1k
                                            EF,
671
97.1k
                                            make<Array>(ast->location, EF, arr_e, false, EF),
672
97.1k
                                            EF,
673
97.1k
                                            false,
674
97.1k
                                            ast->specs,
675
97.1k
                                            EF);
676
97.1k
        desugar(arr, obj_level);
677
97.1k
        return make<ObjectComprehensionSimple>(
678
97.1k
            ast->location,
679
97.1k
            make<Index>(E, EF, var(_arr), EF, false, zero, EF, nullptr, EF, nullptr, EF),
680
97.1k
            make<Local>(ast->location, EF, binds, value),
681
97.1k
            _arr,
682
97.1k
            arr);
683
97.1k
    }
684
685
    void desugar(AST *&ast_, unsigned obj_level)
686
188M
    {
687
188M
        if (auto *ast = dynamic_cast<Apply *>(ast_)) {
688
18.3M
            desugar(ast->target, obj_level);
689
18.3M
            for (ArgParam &arg : ast->args)
690
30.3M
                desugar(arg.expr, obj_level);
691
692
170M
        } else if (auto *ast = dynamic_cast<ApplyBrace *>(ast_)) {
693
214k
            desugar(ast->left, obj_level);
694
214k
            desugar(ast->right, obj_level);
695
214k
            ast_ =
696
214k
                make<Binary>(ast->location, ast->openFodder, ast->left, EF, BOP_PLUS, ast->right);
697
698
170M
        } else if (auto *ast = dynamic_cast<Array *>(ast_)) {
699
2.59M
            for (auto &el : ast->elements)
700
7.81M
                desugar(el.expr, obj_level);
701
702
167M
        } else if (auto *ast = dynamic_cast<ArrayComprehension *>(ast_)) {
703
811k
            for (ComprehensionSpec &spec : ast->specs)
704
1.32M
                desugar(spec.expr, obj_level);
705
811k
            desugar(ast->body, obj_level + 1);
706
707
811k
            ast_ = makeArrayComprehension(ast);
708
709
166M
        } else if (auto *ast = dynamic_cast<Assert *>(ast_)) {
710
915k
            desugar(ast->cond, obj_level);
711
915k
            if (ast->message == nullptr) {
712
67.7k
                ast->message = str(U"Assertion failed.");
713
67.7k
            }
714
915k
            desugar(ast->message, obj_level);
715
915k
            desugar(ast->rest, obj_level);
716
717
            // if cond then rest else error msg
718
915k
            AST *branch_false = make<Error>(ast->location, EF, ast->message);
719
915k
            ast_ = make<Conditional>(
720
915k
                ast->location, ast->openFodder, ast->cond, EF, ast->rest, EF, branch_false);
721
722
165M
        } else if (auto *ast = dynamic_cast<Binary *>(ast_)) {
723
19.7M
            desugar(ast->left, obj_level);
724
19.7M
            desugar(ast->right, obj_level);
725
726
19.7M
            bool invert = false;
727
728
19.7M
            switch (ast->op) {
729
689k
                case BOP_PERCENT: {
730
689k
                    AST *f_mod = make<Index>(
731
689k
                        E, EF, std(), EF, false, str(U"mod"), EF, nullptr, EF, nullptr, EF);
732
689k
                    ArgParams args = {{ast->left, EF}, {ast->right, EF}};
733
689k
                    ast_ = make<Apply>(
734
689k
                        ast->location, ast->openFodder, f_mod, EF, args, false, EF, EF, false);
735
689k
                } break;
736
737
548k
                case BOP_MANIFEST_UNEQUAL: invert = true;
738
548k
                [[fallthrough]];
739
4.07M
                case BOP_MANIFEST_EQUAL: {
740
4.07M
                    ast_ = equals(ast->location, ast->left, ast->right);
741
4.07M
                    if (invert)
742
548k
                        ast_ = make<Unary>(ast->location, ast->openFodder, UOP_NOT, ast_);
743
4.07M
                } break;
744
745
14.9M
                default:;
746
                    // Otherwise don't change it.
747
19.7M
            }
748
749
146M
        } else if (dynamic_cast<const BuiltinFunction *>(ast_)) {
750
            // Nothing to do.
751
752
146M
        } else if (auto *ast = dynamic_cast<Conditional *>(ast_)) {
753
7.42M
            desugar(ast->cond, obj_level);
754
7.42M
            desugar(ast->branchTrue, obj_level);
755
7.42M
            if (ast->branchFalse == nullptr)
756
89.4k
                ast->branchFalse = null();
757
7.42M
            desugar(ast->branchFalse, obj_level);
758
759
138M
        } else if (auto *ast = dynamic_cast<Dollar *>(ast_)) {
760
89.3k
            if (obj_level == 0) {
761
565
                throw StaticError(ast->location, "No top-level object found.");
762
565
            }
763
88.7k
            ast_ = var(id(U"$"));
764
765
138M
        } else if (auto *ast = dynamic_cast<Error *>(ast_)) {
766
1.51M
            desugar(ast->expr, obj_level);
767
768
137M
        } else if (auto *ast = dynamic_cast<Function *>(ast_)) {
769
543k
            desugar(ast->body, obj_level);
770
543k
            desugarParams(ast->params, obj_level);
771
772
136M
        } else if (auto *ast = dynamic_cast<Import *>(ast_)) {
773
            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
774
857
            AST *file = ast->file;
775
857
            desugar(file, obj_level);
776
857
            ast->file = dynamic_cast<LiteralString *>(file);
777
778
136M
        } else if (auto *ast = dynamic_cast<Importstr *>(ast_)) {
779
            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
780
2.21k
            AST *file = ast->file;
781
2.21k
            desugar(file, obj_level);
782
2.21k
            ast->file = dynamic_cast<LiteralString *>(file);
783
784
136M
        } else if (auto *ast = dynamic_cast<Importbin *>(ast_)) {
785
            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
786
2.97k
            AST *file = ast->file;
787
2.97k
            desugar(file, obj_level);
788
2.97k
            ast->file = dynamic_cast<LiteralString *>(file);
789
790
136M
        } else if (auto *ast = dynamic_cast<InSuper *>(ast_)) {
791
21.3k
            desugar(ast->element, obj_level);
792
793
136M
        } else if (auto *ast = dynamic_cast<Index *>(ast_)) {
794
20.2M
            desugar(ast->target, obj_level);
795
20.2M
            if (ast->isSlice) {
796
410k
                if (ast->index == nullptr)
797
52.2k
                    ast->index = null();
798
410k
                desugar(ast->index, obj_level);
799
800
410k
                if (ast->end == nullptr)
801
229k
                    ast->end = null();
802
410k
                desugar(ast->end, obj_level);
803
804
410k
                if (ast->step == nullptr)
805
386k
                    ast->step = null();
806
410k
                desugar(ast->step, obj_level);
807
808
410k
                ast_ = make<Apply>(
809
410k
                    ast->location,
810
410k
                    EF,
811
410k
                    make<Index>(
812
410k
                        E, EF, std(), EF, false, str(U"slice"), EF, nullptr, EF, nullptr, EF),
813
410k
                    EF,
814
410k
                    ArgParams{
815
410k
                        {ast->target, EF},
816
410k
                        {ast->index, EF},
817
410k
                        {ast->end, EF},
818
410k
                        {ast->step, EF},
819
410k
                    },
820
410k
                    false,  // trailing comma
821
410k
                    EF,
822
410k
                    EF,
823
410k
                    false  // tailstrict
824
410k
                );
825
19.8M
            } else {
826
19.8M
                if (ast->id != nullptr) {
827
16.0M
                    assert(ast->index == nullptr);
828
16.0M
                    ast->index = str(ast->id->name);
829
16.0M
                    ast->id = nullptr;
830
16.0M
                }
831
19.8M
                desugar(ast->index, obj_level);
832
19.8M
            }
833
834
116M
        } else if (auto *ast = dynamic_cast<Local *>(ast_)) {
835
5.51M
            for (auto &bind : ast->binds)
836
5.89M
                desugar(bind.body, obj_level);
837
5.51M
            desugar(ast->body, obj_level);
838
839
5.89M
            for (auto &bind : ast->binds) {
840
5.89M
                if (bind.functionSugar) {
841
1.65M
                    desugarParams(bind.params, obj_level);
842
1.65M
                    bind.body = make<Function>(ast->location,
843
1.65M
                                               ast->openFodder,
844
1.65M
                                               bind.parenLeftFodder,
845
1.65M
                                               bind.params,
846
1.65M
                                               false,
847
1.65M
                                               bind.parenRightFodder,
848
1.65M
                                               bind.body);
849
1.65M
                    bind.functionSugar = false;
850
1.65M
                    bind.params.clear();
851
1.65M
                }
852
5.89M
            }
853
854
110M
        } else if (dynamic_cast<const LiteralBoolean *>(ast_)) {
855
            // Nothing to do.
856
857
108M
        } else if (dynamic_cast<const LiteralNumber *>(ast_)) {
858
            // Nothing to do.
859
860
95.0M
        } else if (auto *ast = dynamic_cast<LiteralString *>(ast_)) {
861
27.5M
            if ((ast->tokenKind != LiteralString::RAW_DESUGARED) &&
862
10.9M
                (ast->tokenKind != LiteralString::BLOCK) &&
863
10.9M
                (ast->tokenKind != LiteralString::VERBATIM_DOUBLE) &&
864
10.9M
                (ast->tokenKind != LiteralString::VERBATIM_SINGLE)) {
865
10.9M
                ast->value = jsonnet_string_unescape(ast->location, ast->value);
866
10.9M
            }
867
27.5M
            ast->tokenKind = LiteralString::RAW_DESUGARED;
868
27.5M
            ast->blockIndent.clear();
869
870
67.5M
        } else if (dynamic_cast<const LiteralNull *>(ast_)) {
871
            // Nothing to do.
872
873
66.3M
        } else if (auto *ast = dynamic_cast<DesugaredObject *>(ast_)) {
874
187k
            for (auto &field : ast->fields) {
875
152k
                desugar(field.name, obj_level);
876
152k
                desugar(field.body, obj_level + 1);
877
152k
            }
878
187k
            for (AST *assert : ast->asserts) {
879
8.02k
                desugar(assert, obj_level + 1);
880
8.02k
            }
881
882
66.1M
        } else if (auto *ast = dynamic_cast<Object *>(ast_)) {
883
1.18M
            ast_ = makeObject(ast, obj_level);
884
885
64.9M
        } else if (auto *ast = dynamic_cast<ObjectComprehension *>(ast_)) {
886
97.1k
            ast_ = makeObjectComprehension(ast, obj_level);
887
888
64.8M
        } else if (auto *ast = dynamic_cast<ObjectComprehensionSimple *>(ast_)) {
889
36.2k
            desugar(ast->field, obj_level);
890
36.2k
            desugar(ast->value, obj_level + 1);
891
36.2k
            desugar(ast->array, obj_level);
892
893
64.8M
        } else if (auto *ast = dynamic_cast<Parens *>(ast_)) {
894
            // Strip parens.
895
1.11M
            desugar(ast->expr, obj_level);
896
1.11M
            ast_ = ast->expr;
897
898
63.7M
        } else if (dynamic_cast<const Self *>(ast_)) {
899
            // Nothing to do.
900
901
63.4M
        } else if (auto *ast = dynamic_cast<SuperIndex *>(ast_)) {
902
23.1k
            if (ast->id != nullptr) {
903
2.30k
                assert(ast->index == nullptr);
904
2.30k
                ast->index = str(ast->id->name);
905
2.30k
                ast->id = nullptr;
906
2.30k
            }
907
23.1k
            desugar(ast->index, obj_level);
908
909
63.4M
        } else if (auto *ast = dynamic_cast<Unary *>(ast_)) {
910
2.07M
            desugar(ast->expr, obj_level);
911
912
61.3M
        } else if (dynamic_cast<const Var *>(ast_)) {
913
            // Nothing to do.
914
915
61.3M
        } else {
916
0
            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
917
0
            std::abort();
918
0
        }
919
188M
    }
920
921
22.3k
    DesugaredObject *stdlibAST(std::string filename) {
922
        // Now, implement the std library by wrapping in a local construct.
923
22.3k
        Tokens tokens = jsonnet_lex("std.jsonnet", STD_CODE);
924
22.3k
        AST *std_ast = jsonnet_parse(alloc, tokens);
925
22.3k
        desugar(std_ast, 0);
926
22.3k
        auto *std_obj = dynamic_cast<DesugaredObject *>(std_ast);
927
22.3k
        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
22.3k
        DesugaredObject::Fields &fields = std_obj->fields;
934
959k
        for (unsigned long c = 0; c <= max_builtin; ++c) {
935
937k
            const auto &decl = jsonnet_builtin_decl(c);
936
937k
            auto name = str(decl.name);
937
937k
            auto name_utf8 = "std:" + encode_utf8(decl.name);
938
937k
            auto fnbody = alloc->makeBuiltinBody(E, name_utf8, [this, &decl]()->Identifiers {
939
509k
                Identifiers params;
940
509k
                for (const auto &p : decl.params)
941
752k
                    params.push_back(this->id(p));
942
509k
                return params;
943
509k
            });
944
937k
            auto field = std::find_if(fields.begin(), fields.end(),
945
114M
                [=](const DesugaredObject::Field& f) {
946
114M
                    return static_cast<LiteralString*>(f.name)->value == decl.name;
947
114M
                });
948
937k
            auto fn = make<BuiltinFunction>(E, fnbody);
949
937k
            if (field != fields.end()) {
950
156k
                field->body = fn;
951
781k
            } else {
952
781k
                fields.emplace_back(ObjectField::HIDDEN, name, fn);
953
781k
            }
954
937k
        }
955
22.3k
        fields.emplace_back(
956
22.3k
            ObjectField::HIDDEN, str(U"thisFile"), str(decode_utf8(filename)));
957
22.3k
        return std_obj;
958
22.3k
    }
959
960
    void desugarFile(AST *&ast, std::map<std::string, VmExt> *tlas)
961
13.4k
    {
962
13.4k
        desugar(ast, 0);
963
964
13.4k
        DesugaredObject *std_obj = stdlibAST(ast->location.file);
965
966
13.4k
        std::vector<std::string> empty;
967
13.4k
        auto line_end_blank = Fodder{{FodderElement::LINE_END, 1, 0, empty}};
968
13.4k
        auto line_end = Fodder{{FodderElement::LINE_END, 0, 0, empty}};
969
970
        // local body = ast;
971
        // if std.type(body) == "function") then
972
        //     body(tlas...)
973
        // else
974
        //     body
975
13.4k
        if (tlas != nullptr) {
976
12.1k
            LocationRange tla_loc("Top-level function");
977
12.1k
            ArgParams args;
978
12.1k
            for (const auto &pair : *tlas) {
979
0
                AST *expr;
980
0
                if (pair.second.isCode) {
981
0
                    Tokens tokens = jsonnet_lex("tla:" + pair.first, pair.second.data.c_str());
982
0
                    expr = jsonnet_parse(alloc, tokens);
983
0
                    desugar(expr, 0);
984
0
                } else {
985
0
                    expr = str(decode_utf8(pair.second.data));
986
0
                }
987
                // Add them as named arguments, so order does not matter.
988
0
                args.emplace_back(EF, id(decode_utf8(pair.first)), EF, expr, EF);
989
0
            }
990
12.1k
            const Identifier *body = id(U"top_level");
991
12.1k
            ast =
992
12.1k
                make<Local>(ast->location,
993
12.1k
                            line_end_blank,
994
12.1k
                            singleBind(body, ast),
995
12.1k
                            make<Conditional>(E,
996
12.1k
                                              line_end,
997
12.1k
                                              primitiveEquals(E, type(var(body)), str(U"function")),
998
12.1k
                                              EF,
999
12.1k
                                              make<Apply>(tla_loc,
1000
12.1k
                                                          EF,
1001
12.1k
                                                          make<Var>(E, line_end, body),
1002
12.1k
                                                          EF,
1003
12.1k
                                                          args,
1004
12.1k
                                                          false,  // trailing comma
1005
12.1k
                                                          EF,
1006
12.1k
                                                          EF,
1007
12.1k
                                                          false  // tailstrict
1008
12.1k
                                                          ),
1009
12.1k
                                              line_end,
1010
12.1k
                                              make<Var>(E, line_end, body)));
1011
12.1k
        }
1012
1013
        // local $std = (std.jsonnet stuff); std = $std; ast
1014
        // The standard library is bound to $std, which cannot be overriden,
1015
        // so redefining std won't break expressions that desugar to calls
1016
        // to standard library functions.
1017
13.4k
        ast = make<Local>(ast->location, EF, singleBind(id(U"std"), std()), ast);
1018
13.4k
        ast = make<Local>(ast->location, EF, singleBind(id(U"$std"), std_obj), ast);
1019
13.4k
    }
1020
};
1021
1022
10.1k
DesugaredObject *makeStdlibAST(Allocator *alloc, std::string filename) {
1023
10.1k
    Desugarer desugarer(alloc, true);
1024
10.1k
    return desugarer.stdlibAST(filename);
1025
10.1k
}
1026
1027
void jsonnet_desugar(Allocator *alloc, AST *&ast, std::map<std::string, VmExt> *tlas)
1028
13.4k
{
1029
13.4k
    Desugarer desugarer(alloc);
1030
13.4k
    desugarer.desugarFile(ast, tlas);
1031
13.4k
}
1032
1033
}  // namespace jsonnet::internal