Material throbber: use in tabstrip
[chromium-blink-merge.git] / tools / gn / value_extractors.cc
blob6dfaa2f677e35ff5c315896826e292dc2fdae885
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "tools/gn/value_extractors.h"
7 #include "tools/gn/build_settings.h"
8 #include "tools/gn/err.h"
9 #include "tools/gn/label.h"
10 #include "tools/gn/source_dir.h"
11 #include "tools/gn/source_file.h"
12 #include "tools/gn/target.h"
13 #include "tools/gn/value.h"
15 namespace {
17 // Sets the error and returns false on failure.
18 template<typename T, class Converter>
19 bool ListValueExtractor(const Value& value,
20 std::vector<T>* dest,
21 Err* err,
22 const Converter& converter) {
23 if (!value.VerifyTypeIs(Value::LIST, err))
24 return false;
25 const std::vector<Value>& input_list = value.list_value();
26 dest->resize(input_list.size());
27 for (size_t i = 0; i < input_list.size(); i++) {
28 if (!converter(input_list[i], &(*dest)[i], err))
29 return false;
31 return true;
34 // Like the above version but extracts to a UniqueVector and sets the error if
35 // there are duplicates.
36 template<typename T, class Converter>
37 bool ListValueUniqueExtractor(const Value& value,
38 UniqueVector<T>* dest,
39 Err* err,
40 const Converter& converter) {
41 if (!value.VerifyTypeIs(Value::LIST, err))
42 return false;
43 const std::vector<Value>& input_list = value.list_value();
45 for (const auto& item : input_list) {
46 T new_one;
47 if (!converter(item, &new_one, err))
48 return false;
49 if (!dest->push_back(new_one)) {
50 // Already in the list, throw error.
51 *err = Err(item, "Duplicate item in list");
52 size_t previous_index = dest->IndexOf(new_one);
53 err->AppendSubErr(Err(input_list[previous_index],
54 "This was the previous definition."));
55 return false;
58 return true;
61 struct RelativeFileConverter {
62 RelativeFileConverter(const BuildSettings* build_settings_in,
63 const SourceDir& current_dir_in)
64 : build_settings(build_settings_in),
65 current_dir(current_dir_in) {
67 bool operator()(const Value& v, SourceFile* out, Err* err) const {
68 if (!v.VerifyTypeIs(Value::STRING, err))
69 return false;
70 *out = current_dir.ResolveRelativeFile(v.string_value(),
71 build_settings->root_path_utf8());
72 return true;
74 const BuildSettings* build_settings;
75 const SourceDir& current_dir;
78 struct RelativeDirConverter {
79 RelativeDirConverter(const BuildSettings* build_settings_in,
80 const SourceDir& current_dir_in)
81 : build_settings(build_settings_in),
82 current_dir(current_dir_in) {
84 bool operator()(const Value& v, SourceDir* out, Err* err) const {
85 if (!v.VerifyTypeIs(Value::STRING, err))
86 return false;
87 *out = current_dir.ResolveRelativeDir(v.string_value(),
88 build_settings->root_path_utf8());
89 return true;
91 const BuildSettings* build_settings;
92 const SourceDir& current_dir;
95 // Fills in a label.
96 template<typename T> struct LabelResolver {
97 LabelResolver(const SourceDir& current_dir_in,
98 const Label& current_toolchain_in)
99 : current_dir(current_dir_in),
100 current_toolchain(current_toolchain_in) {}
101 bool operator()(const Value& v, Label* out, Err* err) const {
102 if (!v.VerifyTypeIs(Value::STRING, err))
103 return false;
104 *out = Label::Resolve(current_dir, current_toolchain, v, err);
105 return !err->has_error();
107 const SourceDir& current_dir;
108 const Label& current_toolchain;
111 // Fills the label part of a LabelPtrPair, leaving the pointer null.
112 template<typename T> struct LabelPtrResolver {
113 LabelPtrResolver(const SourceDir& current_dir_in,
114 const Label& current_toolchain_in)
115 : current_dir(current_dir_in),
116 current_toolchain(current_toolchain_in) {}
117 bool operator()(const Value& v, LabelPtrPair<T>* out, Err* err) const {
118 if (!v.VerifyTypeIs(Value::STRING, err))
119 return false;
120 out->label = Label::Resolve(current_dir, current_toolchain, v, err);
121 out->origin = v.origin();
122 return !err->has_error();
124 const SourceDir& current_dir;
125 const Label& current_toolchain;
128 } // namespace
130 bool ExtractListOfStringValues(const Value& value,
131 std::vector<std::string>* dest,
132 Err* err) {
133 if (!value.VerifyTypeIs(Value::LIST, err))
134 return false;
135 const std::vector<Value>& input_list = value.list_value();
136 dest->reserve(input_list.size());
137 for (const auto& item : input_list) {
138 if (!item.VerifyTypeIs(Value::STRING, err))
139 return false;
140 dest->push_back(item.string_value());
142 return true;
145 bool ExtractListOfRelativeFiles(const BuildSettings* build_settings,
146 const Value& value,
147 const SourceDir& current_dir,
148 std::vector<SourceFile>* files,
149 Err* err) {
150 return ListValueExtractor(value, files, err,
151 RelativeFileConverter(build_settings, current_dir));
154 bool ExtractListOfRelativeDirs(const BuildSettings* build_settings,
155 const Value& value,
156 const SourceDir& current_dir,
157 std::vector<SourceDir>* dest,
158 Err* err) {
159 return ListValueExtractor(value, dest, err,
160 RelativeDirConverter(build_settings, current_dir));
163 bool ExtractListOfLabels(const Value& value,
164 const SourceDir& current_dir,
165 const Label& current_toolchain,
166 LabelTargetVector* dest,
167 Err* err) {
168 return ListValueExtractor(value, dest, err,
169 LabelPtrResolver<Target>(current_dir,
170 current_toolchain));
173 bool ExtractListOfUniqueLabels(const Value& value,
174 const SourceDir& current_dir,
175 const Label& current_toolchain,
176 UniqueVector<Label>* dest,
177 Err* err) {
178 return ListValueUniqueExtractor(value, dest, err,
179 LabelResolver<Config>(current_dir,
180 current_toolchain));
183 bool ExtractListOfUniqueLabels(const Value& value,
184 const SourceDir& current_dir,
185 const Label& current_toolchain,
186 UniqueVector<LabelConfigPair>* dest,
187 Err* err) {
188 return ListValueUniqueExtractor(value, dest, err,
189 LabelPtrResolver<Config>(current_dir,
190 current_toolchain));
193 bool ExtractListOfUniqueLabels(const Value& value,
194 const SourceDir& current_dir,
195 const Label& current_toolchain,
196 UniqueVector<LabelTargetPair>* dest,
197 Err* err) {
198 return ListValueUniqueExtractor(value, dest, err,
199 LabelPtrResolver<Target>(current_dir,
200 current_toolchain));
203 bool ExtractRelativeFile(const BuildSettings* build_settings,
204 const Value& value,
205 const SourceDir& current_dir,
206 SourceFile* file,
207 Err* err) {
208 RelativeFileConverter converter(build_settings, current_dir);
209 return converter(value, file, err);