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