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