Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: extensions/renderer/api_signature.cc

Issue 2598123002: [Extensions Bindings] Add support for updateArgumentsPreValidate (Closed)
Patch Set: rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/renderer/api_signature.h" 5 #include "extensions/renderer/api_signature.h"
6 6
7 #include <algorithm>
8
7 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
8 #include "base/values.h" 10 #include "base/values.h"
9 #include "gin/arguments.h" 11 #include "gin/arguments.h"
10 12
11 namespace extensions { 13 namespace extensions {
12 14
13 namespace { 15 namespace {
14 16
15 // A class to help with argument parsing. Note that this uses v8::Locals and 17 // A class to help with argument parsing. Note that this uses v8::Locals and
16 // const&s because it's an implementation detail of the APISignature; this 18 // const&s because it's an implementation detail of the APISignature; this
17 // should *only* be used directly on the stack! 19 // should *only* be used directly on the stack!
18 class ArgumentParser { 20 class ArgumentParser {
19 public: 21 public:
20 ArgumentParser(const std::vector<std::unique_ptr<ArgumentSpec>>& signature, 22 ArgumentParser(v8::Local<v8::Context> context,
21 gin::Arguments* arguments, 23 const std::vector<std::unique_ptr<ArgumentSpec>>& signature,
24 const std::vector<v8::Local<v8::Value>>& arguments,
22 const ArgumentSpec::RefMap& type_refs, 25 const ArgumentSpec::RefMap& type_refs,
23 std::string* error) 26 std::string* error)
24 : context_(arguments->isolate()->GetCurrentContext()), 27 : context_(context),
25 signature_(signature), 28 signature_(signature),
26 arguments_(arguments), 29 arguments_(arguments),
27 type_refs_(type_refs), 30 type_refs_(type_refs),
28 error_(error) {} 31 error_(error) {}
29 32
30 // Tries to parse the arguments against the expected signature. 33 // Tries to parse the arguments against the expected signature.
31 bool ParseArguments(); 34 bool ParseArguments();
32 35
33 protected: 36 protected:
34 v8::Isolate* GetIsolate() { return context_->GetIsolate(); } 37 v8::Isolate* GetIsolate() { return context_->GetIsolate(); }
35 38
36 private: 39 private:
40 v8::Local<v8::Value> next_argument() {
41 return current_index_ < arguments_.size() ?
42 arguments_[current_index_] : v8::Local<v8::Value>();
43 }
44
45 void ConsumeArgument() {
46 current_index_ = std::min(arguments_.size(), current_index_ + 1);
47 }
48
37 // Attempts to match the next argument to the given |spec|. 49 // Attempts to match the next argument to the given |spec|.
38 // If the next argument does not match and |spec| is optional, uses a null 50 // If the next argument does not match and |spec| is optional, uses a null
39 // value. 51 // value.
40 // Returns true on success. 52 // Returns true on success.
41 bool ParseArgument(const ArgumentSpec& spec); 53 bool ParseArgument(const ArgumentSpec& spec);
42 54
43 // Attempts to parse the callback from the given |spec|. Returns true on 55 // Attempts to parse the callback from the given |spec|. Returns true on
44 // success. 56 // success.
45 bool ParseCallback(const ArgumentSpec& spec); 57 bool ParseCallback(const ArgumentSpec& spec);
46 58
47 // Adds a null value to the parsed arguments. 59 // Adds a null value to the parsed arguments.
48 virtual void AddNull() = 0; 60 virtual void AddNull() = 0;
49 // Returns a base::Value to be populated during argument matching. 61 // Returns a base::Value to be populated during argument matching.
50 virtual std::unique_ptr<base::Value>* GetBuffer() = 0; 62 virtual std::unique_ptr<base::Value>* GetBuffer() = 0;
51 // Adds a new parsed argument. 63 // Adds a new parsed argument.
52 virtual void AddParsedArgument(v8::Local<v8::Value> value) = 0; 64 virtual void AddParsedArgument(v8::Local<v8::Value> value) = 0;
53 // Adds the parsed callback. 65 // Adds the parsed callback.
54 virtual void SetCallback(v8::Local<v8::Function> callback) = 0; 66 virtual void SetCallback(v8::Local<v8::Function> callback) = 0;
55 67
56 v8::Local<v8::Context> context_; 68 v8::Local<v8::Context> context_;
57 const std::vector<std::unique_ptr<ArgumentSpec>>& signature_; 69 const std::vector<std::unique_ptr<ArgumentSpec>>& signature_;
58 gin::Arguments* arguments_; 70 const std::vector<v8::Local<v8::Value>>& arguments_;
59 const ArgumentSpec::RefMap& type_refs_; 71 const ArgumentSpec::RefMap& type_refs_;
60 std::string* error_; 72 std::string* error_;
73 size_t current_index_ = 0;
61 74
62 DISALLOW_COPY_AND_ASSIGN(ArgumentParser); 75 DISALLOW_COPY_AND_ASSIGN(ArgumentParser);
63 }; 76 };
64 77
65 class V8ArgumentParser : public ArgumentParser { 78 class V8ArgumentParser : public ArgumentParser {
66 public: 79 public:
67 V8ArgumentParser(const std::vector<std::unique_ptr<ArgumentSpec>>& signature, 80 V8ArgumentParser(v8::Local<v8::Context> context,
68 gin::Arguments* arguments, 81 const std::vector<std::unique_ptr<ArgumentSpec>>& signature,
82 const std::vector<v8::Local<v8::Value>>& arguments,
69 const ArgumentSpec::RefMap& type_refs, 83 const ArgumentSpec::RefMap& type_refs,
70 std::string* error, 84 std::string* error,
71 std::vector<v8::Local<v8::Value>>* values) 85 std::vector<v8::Local<v8::Value>>* values)
72 : ArgumentParser(signature, arguments, type_refs, error), 86 : ArgumentParser(context, signature, arguments, type_refs, error),
73 values_(values) {} 87 values_(values) {}
74 88
75 private: 89 private:
76 void AddNull() override { values_->push_back(v8::Null(GetIsolate())); } 90 void AddNull() override { values_->push_back(v8::Null(GetIsolate())); }
77 std::unique_ptr<base::Value>* GetBuffer() override { return nullptr; } 91 std::unique_ptr<base::Value>* GetBuffer() override { return nullptr; }
78 void AddParsedArgument(v8::Local<v8::Value> value) override { 92 void AddParsedArgument(v8::Local<v8::Value> value) override {
79 values_->push_back(value); 93 values_->push_back(value);
80 } 94 }
81 void SetCallback(v8::Local<v8::Function> callback) override { 95 void SetCallback(v8::Local<v8::Function> callback) override {
82 values_->push_back(callback); 96 values_->push_back(callback);
83 } 97 }
84 98
85 std::vector<v8::Local<v8::Value>>* values_; 99 std::vector<v8::Local<v8::Value>>* values_;
86 100
87 DISALLOW_COPY_AND_ASSIGN(V8ArgumentParser); 101 DISALLOW_COPY_AND_ASSIGN(V8ArgumentParser);
88 }; 102 };
89 103
90 class BaseValueArgumentParser : public ArgumentParser { 104 class BaseValueArgumentParser : public ArgumentParser {
91 public: 105 public:
92 BaseValueArgumentParser( 106 BaseValueArgumentParser(
107 v8::Local<v8::Context> context,
93 const std::vector<std::unique_ptr<ArgumentSpec>>& signature, 108 const std::vector<std::unique_ptr<ArgumentSpec>>& signature,
94 gin::Arguments* arguments, 109 const std::vector<v8::Local<v8::Value>>& arguments,
95 const ArgumentSpec::RefMap& type_refs, 110 const ArgumentSpec::RefMap& type_refs,
96 std::string* error, 111 std::string* error,
97 base::ListValue* list_value) 112 base::ListValue* list_value)
98 : ArgumentParser(signature, arguments, type_refs, error), 113 : ArgumentParser(context, signature, arguments, type_refs, error),
99 list_value_(list_value) {} 114 list_value_(list_value) {}
100 115
101 v8::Local<v8::Function> callback() { return callback_; } 116 v8::Local<v8::Function> callback() { return callback_; }
102 117
103 private: 118 private:
104 void AddNull() override { 119 void AddNull() override {
105 list_value_->Append(base::Value::CreateNullValue()); 120 list_value_->Append(base::Value::CreateNullValue());
106 } 121 }
107 std::unique_ptr<base::Value>* GetBuffer() override { return &last_arg_; } 122 std::unique_ptr<base::Value>* GetBuffer() override { return &last_arg_; }
108 void AddParsedArgument(v8::Local<v8::Value> value) override { 123 void AddParsedArgument(v8::Local<v8::Value> value) override {
(...skipping 26 matching lines...) Expand all
135 size_t end_size = 150 size_t end_size =
136 signature_has_callback ? signature_.size() - 1 : signature_.size(); 151 signature_has_callback ? signature_.size() - 1 : signature_.size();
137 for (size_t i = 0; i < end_size; ++i) { 152 for (size_t i = 0; i < end_size; ++i) {
138 if (!ParseArgument(*signature_[i])) 153 if (!ParseArgument(*signature_[i]))
139 return false; 154 return false;
140 } 155 }
141 156
142 if (signature_has_callback && !ParseCallback(*signature_.back())) 157 if (signature_has_callback && !ParseCallback(*signature_.back()))
143 return false; 158 return false;
144 159
145 if (!arguments_->PeekNext().IsEmpty()) 160 if (current_index_ != arguments_.size())
146 return false; // Extra arguments aren't allowed. 161 return false; // Extra arguments aren't allowed.
147 162
148 return true; 163 return true;
149 } 164 }
150 165
151 bool ArgumentParser::ParseArgument(const ArgumentSpec& spec) { 166 bool ArgumentParser::ParseArgument(const ArgumentSpec& spec) {
152 v8::Local<v8::Value> value = arguments_->PeekNext(); 167 v8::Local<v8::Value> value = next_argument();
153 if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) { 168 if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) {
154 if (!spec.optional()) { 169 if (!spec.optional()) {
155 *error_ = "Missing required argument: " + spec.name(); 170 *error_ = "Missing required argument: " + spec.name();
156 return false; 171 return false;
157 } 172 }
158 // This is safe to call even if |arguments| is at the end (which can happen 173 // This is safe to call even if |arguments| is at the end (which can happen
159 // if n optional arguments are omitted at the end of the signature). 174 // if n optional arguments are omitted at the end of the signature).
160 arguments_->Skip(); 175 ConsumeArgument();
161 176
162 AddNull(); 177 AddNull();
163 return true; 178 return true;
164 } 179 }
165 180
166 if (!spec.ParseArgument(context_, value, type_refs_, GetBuffer(), error_)) { 181 if (!spec.ParseArgument(context_, value, type_refs_, GetBuffer(), error_)) {
167 if (!spec.optional()) { 182 if (!spec.optional()) {
168 *error_ = "Missing required argument: " + spec.name(); 183 *error_ = "Missing required argument: " + spec.name();
169 return false; 184 return false;
170 } 185 }
171 186
172 AddNull(); 187 AddNull();
173 return true; 188 return true;
174 } 189 }
175 190
176 arguments_->Skip(); 191 ConsumeArgument();
177 AddParsedArgument(value); 192 AddParsedArgument(value);
178 return true; 193 return true;
179 } 194 }
180 195
181 bool ArgumentParser::ParseCallback(const ArgumentSpec& spec) { 196 bool ArgumentParser::ParseCallback(const ArgumentSpec& spec) {
182 v8::Local<v8::Value> value = arguments_->PeekNext(); 197 v8::Local<v8::Value> value = next_argument();
183 if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) { 198 if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) {
184 if (!spec.optional()) { 199 if (!spec.optional()) {
185 *error_ = "Missing required argument: " + spec.name(); 200 *error_ = "Missing required argument: " + spec.name();
186 return false; 201 return false;
187 } 202 }
188 arguments_->Skip(); 203 ConsumeArgument();
189 return true; 204 return true;
190 } 205 }
191 206
192 if (!value->IsFunction()) { 207 if (!value->IsFunction()) {
193 *error_ = "Argument is wrong type: " + spec.name(); 208 *error_ = "Argument is wrong type: " + spec.name();
194 return false; 209 return false;
195 } 210 }
196 211
197 arguments_->Skip(); 212 ConsumeArgument();
198 SetCallback(value.As<v8::Function>()); 213 SetCallback(value.As<v8::Function>());
199 return true; 214 return true;
200 } 215 }
201 216
202 } // namespace 217 } // namespace
203 218
204 APISignature::APISignature(const base::ListValue& specification) { 219 APISignature::APISignature(const base::ListValue& specification) {
205 signature_.reserve(specification.GetSize()); 220 signature_.reserve(specification.GetSize());
206 for (const auto& value : specification) { 221 for (const auto& value : specification) {
207 const base::DictionaryValue* param = nullptr; 222 const base::DictionaryValue* param = nullptr;
208 CHECK(value->GetAsDictionary(&param)); 223 CHECK(value->GetAsDictionary(&param));
209 signature_.push_back(base::MakeUnique<ArgumentSpec>(*param)); 224 signature_.push_back(base::MakeUnique<ArgumentSpec>(*param));
210 } 225 }
211 } 226 }
212 227
213 APISignature::~APISignature() {} 228 APISignature::~APISignature() {}
214 229
215 bool APISignature::ParseArgumentsToV8(gin::Arguments* arguments, 230 bool APISignature::ParseArgumentsToV8(
216 const ArgumentSpec::RefMap& type_refs, 231 v8::Local<v8::Context> context,
217 std::vector<v8::Local<v8::Value>>* v8_out, 232 const std::vector<v8::Local<v8::Value>>& arguments,
218 std::string* error) const { 233 const ArgumentSpec::RefMap& type_refs,
234 std::vector<v8::Local<v8::Value>>* v8_out,
235 std::string* error) const {
219 DCHECK(v8_out); 236 DCHECK(v8_out);
220 std::vector<v8::Local<v8::Value>> v8_values; 237 std::vector<v8::Local<v8::Value>> v8_values;
221 V8ArgumentParser parser(signature_, arguments, type_refs, error, &v8_values); 238 V8ArgumentParser parser(
239 context, signature_, arguments, type_refs, error, &v8_values);
222 if (!parser.ParseArguments()) 240 if (!parser.ParseArguments())
223 return false; 241 return false;
224 *v8_out = std::move(v8_values); 242 *v8_out = std::move(v8_values);
225 return true; 243 return true;
226 } 244 }
227 245
228 bool APISignature::ParseArgumentsToJSON( 246 bool APISignature::ParseArgumentsToJSON(
229 gin::Arguments* arguments, 247 v8::Local<v8::Context> context,
248 const std::vector<v8::Local<v8::Value>>& arguments,
230 const ArgumentSpec::RefMap& type_refs, 249 const ArgumentSpec::RefMap& type_refs,
231 std::unique_ptr<base::ListValue>* json_out, 250 std::unique_ptr<base::ListValue>* json_out,
232 v8::Local<v8::Function>* callback_out, 251 v8::Local<v8::Function>* callback_out,
233 std::string* error) const { 252 std::string* error) const {
234 DCHECK(json_out); 253 DCHECK(json_out);
235 DCHECK(callback_out); 254 DCHECK(callback_out);
236 std::unique_ptr<base::ListValue> json = base::MakeUnique<base::ListValue>(); 255 std::unique_ptr<base::ListValue> json = base::MakeUnique<base::ListValue>();
237 BaseValueArgumentParser parser( 256 BaseValueArgumentParser parser(
238 signature_, arguments, type_refs, error, json.get()); 257 context, signature_, arguments, type_refs, error, json.get());
239 if (!parser.ParseArguments()) 258 if (!parser.ParseArguments())
240 return false; 259 return false;
241 *json_out = std::move(json); 260 *json_out = std::move(json);
242 *callback_out = parser.callback(); 261 *callback_out = parser.callback();
243 return true; 262 return true;
244 } 263 }
245 264
246 } // namespace extensions 265 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/api_signature.h ('k') | extensions/renderer/native_extension_bindings_system.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698