Coverage Report

Created: 2025-11-16 06:26

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