Coverage Report

Created: 2025-07-11 06:27

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