/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 ¶ms, unsigned obj_level) |
231 | 8.37M | { |
232 | 10.3M | for (auto ¶m : 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 |