|
|
Created:
8 years, 11 months ago by calamity Modified:
5 years ago Reviewers:
Yoyo Zhou, (unused - use chromium), jstritar, Aaron Boodman, Nico, not at google - send to devlin CC:
aa, jstritar Base URL:
http://git.chromium.org/chromium/src.git@master Visibility:
Public. |
DescriptionCode generation for extensions api
This is a preliminary code review for a code generator. The tool's purpose is to generate the tedious serialization code that needs to be written when defining a new extensions api. It generates from the json files in chrome/common/extensions/api.
As an example usage, chrome/browser/extensions/extension_permissions_api.cc has been changed to use a class generated from permissions.json.
The tool has been integrated into the build system and generates compiling and working code (for permissions.json at least)
BUG=
TEST=
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=119405
Patch Set 1 #Patch Set 2 : cosmetic tidying #Patch Set 3 : added generated files, removed trailing whitespace #
Total comments: 66
Patch Set 4 : some rework #
Total comments: 88
Patch Set 5 : more rework #
Total comments: 66
Patch Set 6 : rework rework #
Total comments: 16
Patch Set 7 : a fistful of rework #
Total comments: 86
Patch Set 8 : switch style guides #Patch Set 9 : switched namespaces, various rework #
Total comments: 40
Patch Set 10 : updated generated files #Patch Set 11 : updated branch, utilized Result, small fixes #
Total comments: 4
Patch Set 12 : silly mistake #Patch Set 13 : remove generated files examples #Patch Set 14 : fix windows path issue #Patch Set 15 : windows path fix #Messages
Total messages: 41 (0 generated)
Sorry, didn't nearly get through this, just a few nitpicks and a medium-level comments. Sending out now because it's 5pm; I'll continue tonight and/or tomorrow. http://codereview.chromium.org/9114036/diff/2001/build/api_gen.gypi File build/api_gen.gypi (right): http://codereview.chromium.org/9114036/diff/2001/build/api_gen.gypi#newcode7 build/api_gen.gypi:7: 'api_gen_dir': '<(DEPTH)/tools/json_schema_compiler', you'll need to rename this file json_schema_compile.gypi and the variables something sensible to go along with that. note I suggested "json_schema_compile" and not "json_schema_compiler" because from what I can tell the convention for gypis is to specify an action rather than the thing that is doing the action (which would be json_schema_compiler). http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... chrome/browser/extensions/extension_permissions_api.cc:19: #include "chrome/common/extensions/api/permissions_api.h" move this up with the other #includes http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... File chrome/browser/extensions/extension_permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... chrome/browser/extensions/extension_permissions_api_helpers.cc:42: return static_cast<DictionaryValue*>(permissions.ToValue()); I reckon ToValue() should return a DictionaryValue* so this cast should be unnecessary. http://codereview.chromium.org/9114036/diff/2001/chrome/chrome_browser.gypi File chrome/chrome_browser.gypi (right): http://codereview.chromium.org/9114036/diff/2001/chrome/chrome_browser.gypi#n... chrome/chrome_browser.gypi:1123: 'browser/extensions/parse_json.h', what's this? http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... File chrome/common/extensions/api/permissions.json (right): http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... chrome/common/extensions/api/permissions.json:4: "generate": true, "compile" seems like a more appropriate name, now http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... File chrome/common/extensions/api/tabs.json (right): http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... chrome/common/extensions/api/tabs.json:4: "generate": true, it's a bit weird to do this now, since you're not using the generated code yet. however; I can see that it's because you've copied it into the the test data, and that it's nice to have it in sync. however #2; it's going to get out of sync anyway, so I wonder if it's better to just revert the changes to this and windows.json and change them back when ready. http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... chrome/common/extensions/api/tabs.json:65: "nogenerate": true, "nocompile" http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... File chrome/common/extensions/api/windows.json (right): http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... chrome/common/extensions/api/windows.json:4: "generate": true, ditto, revert. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/a... File tools/json_schema_compiler/api_gen_util.gyp (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/a... tools/json_schema_compiler/api_gen_util.gyp:1: # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2012 (thought the presubmit checks would pick this up?) http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:56: # TODO(calamity): is variable indent size necessary/a good idea? yeah, doesn't look like you're using it anyway. might as well delete it and add it back if you need it. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:57: def sblock(self, line, indent=INDENT_SIZE): I don't like the names "sblock" and "eblock" much anyway. How about a slightly different API for Code in the first place: Have a block() method, which returns a new, indented Code object that you can append to. In other words, code like this: c.append("foo") c.sblock("bar1") c.append("bar2") c.append("bar3") c.eblock() c.append("baz") would become like this: c.append("foo") c.block() \ .append("bar1") \ .append("bar2") \ .append("bar3") c.append("baz") or c.append("foo") indented = c.block() indented.append("bar1") indented.append("bar2") indented.append("bar3") c.append("bar") likewise, rather than add()ing a Code to the code object, you'd get a new one, like "section()" or something -- which I believe you only need to be able to substitute names across sections of code, right? You'd then factor the code generation to take the Code to generate into, rather than creating a new one internally if needed. I.e. rather than def generate_some_code(self): c = Code() ... return c c.add(generate_some_code()) you'd do def generate_some_code(self, c): ... generate_some_code(c.section()) http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:96: self.append(comment_symbol + comment) return self http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:110: self.code[i] = line % d return self http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:112: def to_string(self): weird to have this method when there's the python __str__ for this idiom. call it "render" or something. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:116: class TypeManager(object): this should be in its own file. so should most classes, really. use your judgement. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:228: class ParamFormat(object): ditto http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/compiler.py:1: # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2012 http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... tools/json_schema_compiler/generate_cc.py:28: # c.append('#include "base/json/json_converter.h"') what's this? http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... tools/json_schema_compiler/generate_cc.py:47: # TODO(calamity): Events TODO should be before the end of the namespaces http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... tools/json_schema_compiler/model.py:7: class ModelT(object): consider putting this in a model/ directory, with a file for each class. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... tools/json_schema_compiler/model.py:8: """Model of the API.""" also, why is every model object suffixed with T? http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... File tools/json_schema_compiler/util.cc (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:17: //TODO(calamity): need to check is list? nah, not unnecessary here. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:42: list = static_cast<base::ListValue*>(maybe_list); explain why you're doing this. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:82: } all of this can be SetStrings(*from, name, out); http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:90: ..? you probably want to remove this method http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... File tools/json_schema_compiler/util.h (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.h:5: #ifndef CHROME_BROWSER_EXTENSIONS_GEN_UTIL_H__ this has the wrong #ifndef guard, but the presubmit checks should pick that up http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.h:19: namespace api_util { yeah, s/extensions/json_schema_compiler/ s/api_util/util/ http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.h:21: bool GetStrings( these all need documentation, since the behaviour is a bit subtle.
http://codereview.chromium.org/9114036/diff/2001/build/api_gen.gypi File build/api_gen.gypi (right): http://codereview.chromium.org/9114036/diff/2001/build/api_gen.gypi#newcode7 build/api_gen.gypi:7: 'api_gen_dir': '<(DEPTH)/tools/json_schema_compiler', On 2012/01/12 06:01:05, kalman wrote: > you'll need to rename this file json_schema_compile.gypi and the variables > something sensible to go along with that. > > note I suggested "json_schema_compile" and not "json_schema_compiler" because > from what I can tell the convention for gypis is to specify an action rather > than the thing that is doing the action (which would be json_schema_compiler). Done. http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... chrome/browser/extensions/extension_permissions_api.cc:19: #include "chrome/common/extensions/api/permissions_api.h" On 2012/01/12 06:01:05, kalman wrote: > move this up with the other #includes Done. http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... File chrome/browser/extensions/extension_permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/2001/chrome/browser/extensions/ex... chrome/browser/extensions/extension_permissions_api_helpers.cc:42: return static_cast<DictionaryValue*>(permissions.ToValue()); On 2012/01/12 06:01:05, kalman wrote: > I reckon ToValue() should return a DictionaryValue* so this cast should be > unnecessary. Done. http://codereview.chromium.org/9114036/diff/2001/chrome/chrome_browser.gypi File chrome/chrome_browser.gypi (right): http://codereview.chromium.org/9114036/diff/2001/chrome/chrome_browser.gypi#n... chrome/chrome_browser.gypi:1123: 'browser/extensions/parse_json.h', On 2012/01/12 06:01:05, kalman wrote: > what's this? Removed. http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... File chrome/common/extensions/api/permissions.json (right): http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... chrome/common/extensions/api/permissions.json:4: "generate": true, On 2012/01/12 06:01:05, kalman wrote: > "compile" seems like a more appropriate name, now Done. http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... File chrome/common/extensions/api/tabs.json (right): http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... chrome/common/extensions/api/tabs.json:4: "generate": true, On 2012/01/12 06:01:05, kalman wrote: > it's a bit weird to do this now, since you're not using the generated code yet. > > however; I can see that it's because you've copied it into the the test data, > and that it's nice to have it in sync. > > however #2; it's going to get out of sync anyway, so I wonder if it's better to > just revert the changes to this and windows.json and change them back when > ready. Reverted. http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... File chrome/common/extensions/api/windows.json (right): http://codereview.chromium.org/9114036/diff/2001/chrome/common/extensions/api... chrome/common/extensions/api/windows.json:4: "generate": true, On 2012/01/12 06:01:05, kalman wrote: > ditto, revert. Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/a... File tools/json_schema_compiler/api_gen_util.gyp (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/a... tools/json_schema_compiler/api_gen_util.gyp:1: # Copyright (c) 2011 The Chromium Authors. All rights reserved. On 2012/01/12 06:01:05, kalman wrote: > 2012 > > (thought the presubmit checks would pick this up?) Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:56: # TODO(calamity): is variable indent size necessary/a good idea? On 2012/01/12 06:01:05, kalman wrote: > yeah, doesn't look like you're using it anyway. might as well delete it and add > it back if you need it. Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:57: def sblock(self, line, indent=INDENT_SIZE): Can you explain what you dislike about the current API? If it's indenting, I've only recently discovered that I've been a total noob and you can just go (c.append("foo") .sblock("bar1") .append("bar2") .append("bar3") .eblock() .append("baz") ) The reason I didn't do this initially is that I didn't know that the python parser would fail without the enclosing parentheses. Pretty lame. On 2012/01/12 06:01:05, kalman wrote: > I don't like the names "sblock" and "eblock" much anyway. How about a slightly > different API for Code in the first place: I put those names because they worked out to 6 characters which is the same as append > > Have a block() method, which returns a new, indented Code object that you can > append to. In other words, code like this: > > c.append("foo") > c.sblock("bar1") > c.append("bar2") > c.append("bar3") > c.eblock() > c.append("baz") > > would become like this: > > c.append("foo") > c.block() \ > .append("bar1") \ > .append("bar2") \ > .append("bar3") > c.append("baz") > > or > > c.append("foo") > indented = c.block() > indented.append("bar1") > indented.append("bar2") > indented.append("bar3") > c.append("bar") > > likewise, rather than add()ing a Code to the code object, you'd get a new one, > like "section()" or something -- which I believe you only need to be able to > substitute names across sections of code, right? > > You'd then factor the code generation to take the Code to generate into, rather > than creating a new one internally if needed. I.e. rather than > > def generate_some_code(self): > c = Code() > ... > return c > > c.add(generate_some_code()) > > you'd do > > def generate_some_code(self, c): > ... > > generate_some_code(c.section()) Considered passing the same code object everywhere, looked messy because functions have a fair number of params already. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:96: self.append(comment_symbol + comment) On 2012/01/12 06:01:05, kalman wrote: > return self Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:110: self.code[i] = line % d On 2012/01/12 06:01:05, kalman wrote: > return self Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:112: def to_string(self): On 2012/01/12 06:01:05, kalman wrote: > weird to have this method when there's the python __str__ for this idiom. > > call it "render" or something. Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:116: class TypeManager(object): On 2012/01/12 06:01:05, kalman wrote: > this should be in its own file. > > so should most classes, really. use your judgement. Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/compiler.py:1: # Copyright (c) 2011 The Chromium Authors. All rights reserved. On 2012/01/12 06:01:05, kalman wrote: > 2012 Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... tools/json_schema_compiler/generate_cc.py:28: # c.append('#include "base/json/json_converter.h"') On 2012/01/12 06:01:05, kalman wrote: > what's this? Don't know, it was in the original spec. You said we wouldn't need it "for now" so I left it commented out. Maybe it was the original name for utils? Removed. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... tools/json_schema_compiler/model.py:8: """Model of the API.""" On 2012/01/12 06:01:05, kalman wrote: > also, why is every model object suffixed with T? It was done so I had some sort of naming convention on all the model classes. I'll get rid of it. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... File tools/json_schema_compiler/util.cc (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:82: } On 2012/01/12 06:01:05, kalman wrote: > all of this can be > > SetStrings(*from, name, out); Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:90: On 2012/01/12 06:01:05, kalman wrote: > ..? > > you probably want to remove this method Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... File tools/json_schema_compiler/util.h (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.h:5: #ifndef CHROME_BROWSER_EXTENSIONS_GEN_UTIL_H__ On 2012/01/12 06:01:05, kalman wrote: > this has the wrong #ifndef guard, but the presubmit checks should pick that up Done. It wasn't in the presubmit checks? Maybe because it's in tools/ http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.h:19: namespace api_util { On 2012/01/12 06:01:05, kalman wrote: > yeah, > > s/extensions/json_schema_compiler/ > s/api_util/util/ Done.
Replying to your questions from that last review; plus a couple of extra things. I'll continue looking at this in more detail now. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:43: """Concatenate another Code object onto this one. call it "concat" then? add is an odd name. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:57: def sblock(self, line, indent=INDENT_SIZE): On 2012/01/12 22:59:20, calamity wrote: > Can you explain what you dislike about the current API? > > If it's indenting, I've only recently discovered that I've been a total noob and > you can just go > (c.append("foo") > .sblock("bar1") > .append("bar2") > .append("bar3") > .eblock() > .append("baz") > ) > > The reason I didn't do this initially is that I didn't know that the python > parser would fail without the enclosing parentheses. Pretty lame. Oh cool, I didn't know that either. I was assuming you had to use \ everywhere. Anyway -- I just find the use of sblock/eblock a bit confusing, particularly passing it a line. Do you really need that? How about something like (c.append('foo') .append('bar1').start_block() .append('bar2') .append('bar3').end_block() .append('baz')) > > > On 2012/01/12 06:01:05, kalman wrote: > > I don't like the names "sblock" and "eblock" much anyway. How about a slightly > > different API for Code in the first place: > > I put those names because they worked out to 6 characters which is the same as > append Cool, you can avoid it if you take my suggestion above. > > > > > Have a block() method, which returns a new, indented Code object that you can > > append to. In other words, code like this: > > > > c.append("foo") > > c.sblock("bar1") > > c.append("bar2") > > c.append("bar3") > > c.eblock() > > c.append("baz") > > > > would become like this: > > > > c.append("foo") > > c.block() \ > > .append("bar1") \ > > .append("bar2") \ > > .append("bar3") > > c.append("baz") > > > > or > > > > c.append("foo") > > indented = c.block() > > indented.append("bar1") > > indented.append("bar2") > > indented.append("bar3") > > c.append("bar") > > > > > likewise, rather than add()ing a Code to the code object, you'd get a new one, > > like "section()" or something -- which I believe you only need to be able to > > substitute names across sections of code, right? > > > > You'd then factor the code generation to take the Code to generate into, > rather > > than creating a new one internally if needed. I.e. rather than > > > > def generate_some_code(self): > > c = Code() > > ... > > return c > > > > c.add(generate_some_code()) > > > > you'd do > > > > def generate_some_code(self, c): > > ... > > > > generate_some_code(c.section()) > > Considered passing the same code object everywhere, looked messy because > functions have a fair number of params already. Heh, well parameter arguments are cheap. I wouldn't worry about that. But yeah, I'm just being an API astronaut*; I think that what I wrote up there is neat, but after sleeping, don't worry about it; it's too much work to go and rewrite stuff. * as opposed to an architecture astronaut. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:99: """Goes through each line and interpolates using the given dict. Explain why you need to have this method at all, rather than just using normal string interpolation everywhere. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... tools/json_schema_compiler/generate_cc.py:28: # c.append('#include "base/json/json_converter.h"') On 2012/01/12 22:59:20, calamity wrote: > On 2012/01/12 06:01:05, kalman wrote: > > what's this? > > Don't know, it was in the original spec. You said we wouldn't need it "for now" > so I left it commented out. Maybe it was the original name for utils? > > Removed. Oh yeah, never mind about that. Sorry.
http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:57: def sblock(self, line, indent=INDENT_SIZE): On 2012/01/13 00:07:27, kalman wrote: > On 2012/01/12 22:59:20, calamity wrote: > > Can you explain what you dislike about the current API? > > > > If it's indenting, I've only recently discovered that I've been a total noob > and > > you can just go > > (c.append("foo") > > .sblock("bar1") > > .append("bar2") > > .append("bar3") > > .eblock() > > .append("baz") > > ) > > > > The reason I didn't do this initially is that I didn't know that the python > > parser would fail without the enclosing parentheses. Pretty lame. > > Oh cool, I didn't know that either. I was assuming you had to use \ everywhere. > > Anyway -- I just find the use of sblock/eblock a bit confusing, particularly > passing it a line. Do you really need that? How about something like > > (c.append('foo') > .append('bar1').start_block() > .append('bar2') > .append('bar3').end_block() > .append('baz')) > > > > > > > On 2012/01/12 06:01:05, kalman wrote: > > > I don't like the names "sblock" and "eblock" much anyway. How about a > slightly > > > different API for Code in the first place: > > > > I put those names because they worked out to 6 characters which is the same as > > append > > Cool, you can avoid it if you take my suggestion above. > > > > > > > > > Have a block() method, which returns a new, indented Code object that you > can > > > append to. In other words, code like this: > > > > > > c.append("foo") > > > c.sblock("bar1") > > > c.append("bar2") > > > c.append("bar3") > > > c.eblock() > > > c.append("baz") > > > > > > would become like this: > > > > > > c.append("foo") > > > c.block() \ > > > .append("bar1") \ > > > .append("bar2") \ > > > .append("bar3") > > > c.append("baz") > > > > > > or > > > > > > c.append("foo") > > > indented = c.block() > > > indented.append("bar1") > > > indented.append("bar2") > > > indented.append("bar3") > > > c.append("bar") > > > > > > > > likewise, rather than add()ing a Code to the code object, you'd get a new > one, > > > like "section()" or something -- which I believe you only need to be able to > > > substitute names across sections of code, right? > > > > > > You'd then factor the code generation to take the Code to generate into, > > rather > > > than creating a new one internally if needed. I.e. rather than > > > > > > def generate_some_code(self): > > > c = Code() > > > ... > > > return c > > > > > > c.add(generate_some_code()) > > > > > > you'd do > > > > > > def generate_some_code(self, c): > > > ... > > > > > > generate_some_code(c.section()) > > > > Considered passing the same code object everywhere, looked messy because > > functions have a fair number of params already. > > Heh, well parameter arguments are cheap. I wouldn't worry about that. > > But yeah, I'm just being an API astronaut*; I think that what I wrote up there > is neat, but after sleeping, don't worry about it; it's too much work to go and > rewrite stuff. > > > * as opposed to an architecture astronaut. Or similarly, (c.append('foo') .append('bar1').indent() .append('bar2') .append('bar3').unindent() .append('baz')) hah. I prefer the aesthetic of the former (start_block/end_block) but indent/unindent might be more accurate. The "hah" is because you had this a while ago.
http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:57: def sblock(self, line, indent=INDENT_SIZE): On 2012/01/13 00:07:27, kalman wrote: > On 2012/01/12 22:59:20, calamity wrote: > > Can you explain what you dislike about the current API? > > > > If it's indenting, I've only recently discovered that I've been a total noob > and > > you can just go > > (c.append("foo") > > .sblock("bar1") > > .append("bar2") > > .append("bar3") > > .eblock() > > .append("baz") > > ) > > > > The reason I didn't do this initially is that I didn't know that the python > > parser would fail without the enclosing parentheses. Pretty lame. > > Oh cool, I didn't know that either. I was assuming you had to use \ everywhere. > > Anyway -- I just find the use of sblock/eblock a bit confusing, particularly > passing it a line. Do you really need that? How about something like > > (c.append('foo') > .append('bar1').start_block() > .append('bar2') > .append('bar3').end_block() > .append('baz')) > It was more error proof. Calling unindent _after_ the append is problems. Especially since the reversal is necessary. You wouldn't actually call .append.end_block(), you'd call .end_block().append() when there are conditions so the end_block is always run. (c.append('foo') .append('bar1').start_block() ) if condition1: (c.append('bar2') .append('bar3') ) else: (c.append('bar4') .append('bar5') ) c.end_block().append('baz')) ^^^^^^^^^^^^^^^^^^ Fail bait. > > > > > > On 2012/01/12 06:01:05, kalman wrote: > > > I don't like the names "sblock" and "eblock" much anyway. How about a > slightly > > > different API for Code in the first place: > > > > I put those names because they worked out to 6 characters which is the same as > > append > > Cool, you can avoid it if you take my suggestion above. > > > > > > > > > Have a block() method, which returns a new, indented Code object that you > can > > > append to. In other words, code like this: > > > > > > c.append("foo") > > > c.sblock("bar1") > > > c.append("bar2") > > > c.append("bar3") > > > c.eblock() > > > c.append("baz") > > > > > > would become like this: > > > > > > c.append("foo") > > > c.block() \ > > > .append("bar1") \ > > > .append("bar2") \ > > > .append("bar3") > > > c.append("baz") > > > > > > or > > > > > > c.append("foo") > > > indented = c.block() > > > indented.append("bar1") > > > indented.append("bar2") > > > indented.append("bar3") > > > c.append("bar") > > > > > > > > likewise, rather than add()ing a Code to the code object, you'd get a new > one, > > > like "section()" or something -- which I believe you only need to be able to > > > substitute names across sections of code, right? > > > > > > You'd then factor the code generation to take the Code to generate into, > > rather > > > than creating a new one internally if needed. I.e. rather than > > > > > > def generate_some_code(self): > > > c = Code() > > > ... > > > return c > > > > > > c.add(generate_some_code()) > > > > > > you'd do > > > > > > def generate_some_code(self, c): > > > ... > > > > > > generate_some_code(c.section()) > > > > Considered passing the same code object everywhere, looked messy because > > functions have a fair number of params already. > > Heh, well parameter arguments are cheap. I wouldn't worry about that. > > But yeah, I'm just being an API astronaut*; I think that what I wrote up there > is neat, but after sleeping, don't worry about it; it's too much work to go and > rewrite stuff. > > > * as opposed to an architecture astronaut. I'm also more partial to a merge-y approach because each function is more encapsulated and it becomes very obvious where things mess up. Otherwise for the same safety I'd need checks to enforce code segments not touching each other inside the Code class.
Next round. Haven't looked at the type checker, nor the tests. Also haven't gone through the C/H generators too closely though I think a bunch of the comments I made in the other files will apply to them too. I'm going to have lunch; ping me when you've gone through these. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:57: def sblock(self, line, indent=INDENT_SIZE): On 2012/01/13 00:40:23, calamity wrote: > On 2012/01/13 00:07:27, kalman wrote: > > On 2012/01/12 22:59:20, calamity wrote: > > > Can you explain what you dislike about the current API? > > > > > > If it's indenting, I've only recently discovered that I've been a total noob > > and > > > you can just go > > > (c.append("foo") > > > .sblock("bar1") > > > .append("bar2") > > > .append("bar3") > > > .eblock() > > > .append("baz") > > > ) > > > > > > The reason I didn't do this initially is that I didn't know that the python > > > parser would fail without the enclosing parentheses. Pretty lame. > > > > Oh cool, I didn't know that either. I was assuming you had to use \ > everywhere. > > > > Anyway -- I just find the use of sblock/eblock a bit confusing, particularly > > passing it a line. Do you really need that? How about something like > > > > (c.append('foo') > > .append('bar1').start_block() > > .append('bar2') > > .append('bar3').end_block() > > .append('baz')) > > > > It was more error proof. Calling unindent _after_ the append is problems. > > Especially since the reversal is necessary. You wouldn't actually call > .append.end_block(), you'd call .end_block().append() when there are conditions > so the end_block is always run. > > (c.append('foo') > .append('bar1').start_block() > ) > if condition1: > (c.append('bar2') > .append('bar3') > ) > else: > (c.append('bar4') > .append('bar5') > ) > c.end_block().append('baz')) > ^^^^^^^^^^^^^^^^^^ > Fail bait. > I don't understand what you mean... surely it's pretty clear what (un)indent would do? Never mind, though. > > > > > > > > > On 2012/01/12 06:01:05, kalman wrote: > > > > I don't like the names "sblock" and "eblock" much anyway. How about a > > slightly > > > > different API for Code in the first place: > > > > > > I put those names because they worked out to 6 characters which is the same > as > > > append > > > > Cool, you can avoid it if you take my suggestion above. > > > > > > > > > > > > > Have a block() method, which returns a new, indented Code object that you > > can > > > > append to. In other words, code like this: > > > > > > > > c.append("foo") > > > > c.sblock("bar1") > > > > c.append("bar2") > > > > c.append("bar3") > > > > c.eblock() > > > > c.append("baz") > > > > > > > > would become like this: > > > > > > > > c.append("foo") > > > > c.block() \ > > > > .append("bar1") \ > > > > .append("bar2") \ > > > > .append("bar3") > > > > c.append("baz") > > > > > > > > or > > > > > > > > c.append("foo") > > > > indented = c.block() > > > > indented.append("bar1") > > > > indented.append("bar2") > > > > indented.append("bar3") > > > > c.append("bar") > > > > > > > > > > > likewise, rather than add()ing a Code to the code object, you'd get a new > > one, > > > > like "section()" or something -- which I believe you only need to be able > to > > > > substitute names across sections of code, right? > > > > > > > > You'd then factor the code generation to take the Code to generate into, > > > rather > > > > than creating a new one internally if needed. I.e. rather than > > > > > > > > def generate_some_code(self): > > > > c = Code() > > > > ... > > > > return c > > > > > > > > c.add(generate_some_code()) > > > > > > > > you'd do > > > > > > > > def generate_some_code(self, c): > > > > ... > > > > > > > > generate_some_code(c.section()) > > > > > > Considered passing the same code object everywhere, looked messy because > > > functions have a fair number of params already. > > > > Heh, well parameter arguments are cheap. I wouldn't worry about that. > > > > But yeah, I'm just being an API astronaut*; I think that what I wrote up there > > is neat, but after sleeping, don't worry about it; it's too much work to go > and > > rewrite stuff. > > > > > > * as opposed to an architecture astronaut. > > I'm also more partial to a merge-y approach because each function is more > encapsulated and it becomes very obvious where things mess up. Otherwise for the > same safety I'd need checks to enforce code segments not touching each other > inside the Code class. Fair enough. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:20: // DO NOT EDIT.""" This is a specific to C/C++, so code.py doesn't seem like the right place for it. How about having a shared file for c++ code generation which both generate_cc and generate_h can use. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:23: COMMENT_LENGTH = 80 put as members / arguments in the constructor of Code, with default values set to these. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:24: class Code(object): is explicitly extending object necessary? http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:25: """A convenience object for appending code. s/appending/constructing/ or something. Also add that all methods (besides |render|) return self. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:27: Logically each object should be a block of code.""" these docstrings should have a blank line after them, and the closing """ should be on a line of its own. (same for every class) http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Comments http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:30: # TODO(calamity): Indent stack probably isn't necessary you can delete this comment and _indent_list, right? http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:32: self.indent_level = 0 these should have an _ prefix http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:38: This will strip trailing whitespace.""" ... newline if line is not specified. Trailing whitespace is stripped. """ more concise documentation ftw. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:42: def add(self, obj): I wonder if it's more convenient to just merge this into append. That would let functions return either a string or a code block depending on what they were feeling like, and it kind of looks nicer IMO. def append(self, content=''): if isinstance(content, str): self.code.append(((' ' * self.indent_level)) + line).rstrip() elif isinstance(content, Code): for line in content.code: self.append(line) else: raise TypeError('blah type not supported blah') return self you'd need to carefully document that too, of course. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:56: # TODO(calamity): is variable indent size necessary/a good idea? TODO unnecessary http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:58: """Starts a code block. """Starts a code block, by appending a line of code then increasing the indent level. """ by the way, for consistency, this method should probably have line='' too. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:66: """Ends a code block. """Ends a code block, by decreasing the indent level then appending a line (or a blank line if none is given. """ http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:100: Raises type error if passed something that isn't a dict.""" "Raises type error" comment is unnecessary. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:113: """Returns the code joined together as a string.""" """Renders the Code as a string. """ http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:116: def cpp_name(s): this also belongs in a c++ util class http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:9: class CC_Generator(object): I like this name, so the file should be called cc_generator.py. Also I believe that the style is just "class CCGenerator:" ... http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:17: """Generates the .cc code for a single namespace. """Generates a code.Code object with the .cc code for a namespace. """ http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:24: (c.append(code.CHROMIUM_LICENSE).append() put the second .append() on its own line; this would mirror the generated code more closely. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:29: # .append('#include "base/json/json_converter.h"') delete http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:31: .append('namespace extensions {') "extensions" needs to be taken from the command-line options. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:40: c.add(self.generate_type(tipe)) pull the last "c.append()" out of generate_type and into here. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:47: c.append('} // namespace extensions') ditto extensions http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:53: """Generates the function definitions for a type in the namespace.""" ... for a type. """ (no need for "in the namespace") http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:55: classname = '%s' % (tipe.name) can delete this line and inline it? ... c.substitute({'classname': tipe.name}) http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:88: c.append('if (!json_schema_compiler::util::GetOptionalTypes<%(type)s>(*dict,') this line is too long. this makes me think though -- I think it would be nice to have a few global variables that are automatically resolved at the top level (although probably by the Code object, since the Code object needs to know about any global substitutions so that unresolved ones can be error checked, anyway) Things like - the path to the utils ('json_schema_compiler::util' in this case) - the namepace that everything is being generated to ('extensions' in this case) this line could then become c.append("if (!%(global.utils)s::GetOptionalTypes(...)") likewise where you've written "extensions", could be %(global.namespace)s or whatever you've been calling it. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:255: c.append('result->Set("%(argname)s", %(argname)s.ToValue());') SetWithoutPathExpansion (need to audit this whole file for that..) http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/generate_h.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:9: class H_Generator(object): Same comment applies here as to CCGenerator. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:17: """Generates the .h code for self.namespace. ditto http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:50: c.append('namespace extensions {') ditto http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:100: c.append('// Returns a new DictionaryValue representing the serialized form') line too long http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:84: members actually exist. not sure what this sentence means...
Another few comments; done for the day. Note that there are quite a few places where members should be private; reading the style guide, I didn't realise that single-underscore was protected. So, you'll need to double-underscore things. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:58: assert len(json['parameters']) <= 1 add a message like, "Callbacks can have at most a single parameter". http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/type_manager.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:10: class TypeManager(object): this class is specific enough to C to warrant it being called CppTypeManager or something. or perhaps CppTypeGenerator. if you do decide to do that, all my comments saying e.g. s/get_type/get_cpp_type/ would be unnecessary. the only thing general is type_dependencies. maybe that should be pulled into the model. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:11: """Manages the types of properties and provides utlities for getting the s/utlities/utilities/ http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:19: def get_type(self, prop): get_cpp_type http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:49: def parameter_declaration(self, param, type_modifiers=None, generate_cpp_parameter(...) perhaps? though it seems to me like it isn't much of a win having this function at all. Its uses are simple enough to just inline the logic; they're always const references so the ParameterType and all that is also unnecessary. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:65: def get_generic_type(self, prop): this should probably be merged into get_type, with an extra parameter like "pad_for_generics" or something. def get_type(self, property, pad_for_generics=false): ... particularly since the line return 'std::vector<%s>' % self.get_type(prop.item_type) should really be padded. return 'std::vector<%s>' % self.get_type(prop.item_type, pad_for_generics=true) kinda neat. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:76: def resolve_generated_includes(self): call this like, generate_cpp_includes http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:98: def type_dependencies(self, prop): private, so __type_dependencies
http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:43: """Concatenate another Code object onto this one. On 2012/01/13 00:07:27, kalman wrote: > call it "concat" then? add is an odd name. Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:99: """Goes through each line and interpolates using the given dict. On 2012/01/13 00:07:27, kalman wrote: > Explain why you need to have this method at all, rather than just using normal > string interpolation everywhere. Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/c... tools/json_schema_compiler/code.py:228: class ParamFormat(object): On 2012/01/12 06:01:05, kalman wrote: > ditto Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... tools/json_schema_compiler/generate_cc.py:47: # TODO(calamity): Events On 2012/01/12 06:01:05, kalman wrote: > TODO should be before the end of the namespaces ??? So move this TODO up? http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... tools/json_schema_compiler/model.py:7: class ModelT(object): On 2012/01/12 06:01:05, kalman wrote: > consider putting this in a model/ directory, with a file for each class. Any particular reason for doing this? http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... File tools/json_schema_compiler/util.cc (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:17: //TODO(calamity): need to check is list? On 2012/01/12 06:01:05, kalman wrote: > nah, not unnecessary here. Removed. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.cc:42: list = static_cast<base::ListValue*>(maybe_list); On 2012/01/12 06:01:05, kalman wrote: > explain why you're doing this. Done. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... File tools/json_schema_compiler/util.h (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/u... tools/json_schema_compiler/util.h:21: bool GetStrings( On 2012/01/12 06:01:05, kalman wrote: > these all need documentation, since the behaviour is a bit subtle. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:20: // DO NOT EDIT.""" On 2012/01/13 02:14:09, kalman wrote: > This is a specific to C/C++, so code.py doesn't seem like the right place for > it. How about having a shared file for c++ code generation which both > generate_cc and generate_h can use. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:23: COMMENT_LENGTH = 80 On 2012/01/13 02:14:09, kalman wrote: > put as members / arguments in the constructor of Code, with default values set > to these. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:24: class Code(object): On 2012/01/13 02:14:09, kalman wrote: > is explicitly extending object necessary? It defines it as a "new style" class. Not sure if that's necessary though (I know you need it for subclassing, but maybe there's something else about it?) http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:25: """A convenience object for appending code. On 2012/01/13 02:14:09, kalman wrote: > s/appending/constructing/ > > or something. > > Also add that all methods (besides |render|) return self. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:27: Logically each object should be a block of code.""" On 2012/01/13 02:14:09, kalman wrote: > these docstrings should have a blank line after them, and the closing """ should > be on a line of its own. > > (same for every class) > > http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Comments Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:30: # TODO(calamity): Indent stack probably isn't necessary On 2012/01/13 02:14:09, kalman wrote: > you can delete this comment and _indent_list, right? Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:32: self.indent_level = 0 On 2012/01/13 02:14:09, kalman wrote: > these should have an _ prefix Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:38: This will strip trailing whitespace.""" On 2012/01/13 02:14:09, kalman wrote: > ... newline if line is not specified. Trailing whitespace is stripped. > """ > > more concise documentation ftw. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:42: def add(self, obj): On 2012/01/13 02:14:09, kalman wrote: > I wonder if it's more convenient to just merge this into append. That would let > functions return either a string or a code block depending on what they were > feeling like, and it kind of looks nicer IMO. > > def append(self, content=''): > if isinstance(content, str): > self.code.append(((' ' * self.indent_level)) + line).rstrip() > elif isinstance(content, Code): > for line in content.code: > self.append(line) > else: > raise TypeError('blah type not supported blah') > return self > > you'd need to carefully document that too, of course. Maybe. Might be unpythonic. code.Code is meant to be similar to the list api which uses append for adding an element and + for adding another list. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:56: # TODO(calamity): is variable indent size necessary/a good idea? On 2012/01/13 02:14:09, kalman wrote: > TODO unnecessary Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:58: """Starts a code block. On 2012/01/13 02:14:09, kalman wrote: > """Starts a code block, by appending a line of code then increasing the indent > level. > """ > > by the way, for consistency, this method should probably have line='' too. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:66: """Ends a code block. On 2012/01/13 02:14:09, kalman wrote: > """Ends a code block, by decreasing the indent level then appending a line (or > a blank line if none is given. > """ Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:100: Raises type error if passed something that isn't a dict.""" On 2012/01/13 02:14:09, kalman wrote: > "Raises type error" comment is unnecessary. The style guide says it should list exceptions it raises? To be honest, these should be documented a lot better than they are. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:113: """Returns the code joined together as a string.""" On 2012/01/13 02:14:09, kalman wrote: > """Renders the Code as a string. > """ Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:116: def cpp_name(s): On 2012/01/13 02:14:09, kalman wrote: > this also belongs in a c++ util class Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:9: class CC_Generator(object): On 2012/01/13 02:14:09, kalman wrote: > I like this name, so the file should be called cc_generator.py. > > Also I believe that the style is just "class CCGenerator:" ... Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:17: """Generates the .cc code for a single namespace. On 2012/01/13 02:14:09, kalman wrote: > """Generates a code.Code object with the .cc code for a namespace. > """ Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:24: (c.append(code.CHROMIUM_LICENSE).append() On 2012/01/13 02:14:09, kalman wrote: > put the second .append() on its own line; this would mirror the generated code > more closely. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:29: # .append('#include "base/json/json_converter.h"') On 2012/01/13 02:14:09, kalman wrote: > delete Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:31: .append('namespace extensions {') On 2012/01/13 02:14:09, kalman wrote: > "extensions" needs to be taken from the command-line options. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:40: c.add(self.generate_type(tipe)) On 2012/01/13 02:14:09, kalman wrote: > pull the last "c.append()" out of generate_type and into here. Done. Also did the same with all other "c.append()"s at the end of functions http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:47: c.append('} // namespace extensions') On 2012/01/13 02:14:09, kalman wrote: > ditto extensions Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:53: """Generates the function definitions for a type in the namespace.""" On 2012/01/13 02:14:09, kalman wrote: > ... for a type. > """ > > (no need for "in the namespace") Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:55: classname = '%s' % (tipe.name) On 2012/01/13 02:14:09, kalman wrote: > can delete this line and inline it? > > ... > c.substitute({'classname': tipe.name}) Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:88: c.append('if (!json_schema_compiler::util::GetOptionalTypes<%(type)s>(*dict,') On 2012/01/13 02:14:09, kalman wrote: > this line is too long. > > this makes me think though -- I think it would be nice to have a few global > variables that are automatically resolved at the top level (although probably by > the Code object, since the Code object needs to know about any global > substitutions so that unresolved ones can be error checked, anyway) > > Things like > - the path to the utils ('json_schema_compiler::util' in this case) > - the namepace that everything is being generated to ('extensions' in this > case) > > this line could then become > > c.append("if (!%(global.utils)s::GetOptionalTypes(...)") > > likewise where you've written "extensions", could be %(global.namespace)s or > whatever you've been calling it. Yeah, but as always it's a tradeoff between usability and readability. Wouldn't that introduce global state? http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:104: c.append(' return false;') Clearly this if block is going to grow. On a dev branch I've pulled this into it's own class that deals with interactions with util.cc. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:255: c.append('result->Set("%(argname)s", %(argname)s.ToValue());') On 2012/01/13 02:14:09, kalman wrote: > SetWithoutPathExpansion > > (need to audit this whole file for that..) Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/generate_h.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:9: class H_Generator(object): On 2012/01/13 02:14:09, kalman wrote: > Same comment applies here as to CCGenerator. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:17: """Generates the .h code for self.namespace. On 2012/01/13 02:14:09, kalman wrote: > ditto Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:50: c.append('namespace extensions {') On 2012/01/13 02:14:09, kalman wrote: > ditto Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_h.py:100: c.append('// Returns a new DictionaryValue representing the serialized form') On 2012/01/13 02:14:09, kalman wrote: > line too long Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:58: assert len(json['parameters']) <= 1 On 2012/01/13 06:45:55, kalman wrote: > add a message like, "Callbacks can have at most a single parameter". Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:116: STRING, FUNDAMENTAL, ARRAY, REF, CHOICES, OBJECT = range(6) PropertyType.STRING is unused. On dev branch, FUNDAMENTAL is replaced with INTEGER, STRING, DOUBLE, BOOLEAN because checking the json_type is dodgy (Should work as much as possible with code rather than strings). http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/type_manager.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:10: class TypeManager(object): On 2012/01/13 06:45:55, kalman wrote: > this class is specific enough to C to warrant it being called CppTypeManager or > something. or perhaps CppTypeGenerator. > > if you do decide to do that, all my comments saying e.g. > s/get_type/get_cpp_type/ would be unnecessary. > > the only thing general is type_dependencies. maybe that should be pulled into > the model. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:11: """Manages the types of properties and provides utlities for getting the On 2012/01/13 06:45:55, kalman wrote: > s/utlities/utilities/ Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:19: def get_type(self, prop): On 2012/01/13 06:45:55, kalman wrote: > get_cpp_type Changed class to CppTypeManager. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:49: def parameter_declaration(self, param, type_modifiers=None, On 2012/01/13 06:45:55, kalman wrote: > generate_cpp_parameter(...) perhaps? > > though it seems to me like it isn't much of a win having this function at all. > Its uses are simple enough to just inline the logic; they're always const > references so the ParameterType and all that is also unnecessary. I'll remove it for now. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:65: def get_generic_type(self, prop): On 2012/01/13 06:45:55, kalman wrote: > this should probably be merged into get_type, with an extra parameter like > "pad_for_generics" or something. > > def get_type(self, property, pad_for_generics=false): > ... > > particularly since the line > return 'std::vector<%s>' % self.get_type(prop.item_type) > should really be padded. > return 'std::vector<%s>' % self.get_type(prop.item_type, > pad_for_generics=true) > > kinda neat. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:76: def resolve_generated_includes(self): On 2012/01/13 06:45:55, kalman wrote: > call this like, generate_cpp_includes Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager.py:98: def type_dependencies(self, prop): On 2012/01/13 06:45:55, kalman wrote: > private, so __type_dependencies Done.
Just replying to your comments, will go over the new code now. http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/g... tools/json_schema_compiler/generate_cc.py:47: # TODO(calamity): Events On 2012/01/16 04:01:06, calamity wrote: > On 2012/01/12 06:01:05, kalman wrote: > > TODO should be before the end of the namespaces > > ??? So move this TODO up? Well you'd generate the events after the functions, not after the end of the namespaces. It's a nitpick :) http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/2001/tools/json_schema_compiler/m... tools/json_schema_compiler/model.py:7: class ModelT(object): On 2012/01/16 04:01:06, calamity wrote: > On 2012/01/12 06:01:05, kalman wrote: > > consider putting this in a model/ directory, with a file for each class. > > Any particular reason for doing this? Yes, so that you can have - a different file for each class (good, easier to navigate code) - the model classes in the same place (ditto) However, it seems just as convenient to have these in the same place, particularly so that you can have like from model import Namespace so I guess it's not considered so important to have each class in its own file. Yeah, don't worry about it. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:24: class Code(object): On 2012/01/16 04:01:06, calamity wrote: > On 2012/01/13 02:14:09, kalman wrote: > > is explicitly extending object necessary? > > It defines it as a "new style" class. Not sure if that's necessary though (I > know you need it for subclassing, but maybe there's something else about it?) Ah... alright. If it's like Java, classes automatically/implicitly extend from object, it's weird to see "class Blah extends Object". But it seems like python behaves differently. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:42: def add(self, obj): On 2012/01/16 04:01:06, calamity wrote: > On 2012/01/13 02:14:09, kalman wrote: > > I wonder if it's more convenient to just merge this into append. That would > let > > functions return either a string or a code block depending on what they were > > feeling like, and it kind of looks nicer IMO. > > > > def append(self, content=''): > > if isinstance(content, str): > > self.code.append(((' ' * self.indent_level)) + line).rstrip() > > elif isinstance(content, Code): > > for line in content.code: > > self.append(line) > > else: > > raise TypeError('blah type not supported blah') > > return self > > > > you'd need to carefully document that too, of course. > > Maybe. Might be unpythonic. code.Code is meant to be similar to the list api > which uses append for adding an element and + for adding another list. Cool, don't worry about it then. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:100: Raises type error if passed something that isn't a dict.""" On 2012/01/16 04:01:06, calamity wrote: > On 2012/01/13 02:14:09, kalman wrote: > > "Raises type error" comment is unnecessary. > > The style guide says it should list exceptions it raises? To be honest, these > should be documented a lot better than they are. This isn't really an exception though, it's a programmer error. In fact I think it should be an assertion. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/generate_cc.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:88: c.append('if (!json_schema_compiler::util::GetOptionalTypes<%(type)s>(*dict,') On 2012/01/16 04:01:06, calamity wrote: > On 2012/01/13 02:14:09, kalman wrote: > > this line is too long. > > > > this makes me think though -- I think it would be nice to have a few global > > variables that are automatically resolved at the top level (although probably > by > > the Code object, since the Code object needs to know about any global > > substitutions so that unresolved ones can be error checked, anyway) > > > > Things like > > - the path to the utils ('json_schema_compiler::util' in this case) > > - the namepace that everything is being generated to ('extensions' in this > > case) > > > > this line could then become > > > > c.append("if (!%(global.utils)s::GetOptionalTypes(...)") > > > > likewise where you've written "extensions", could be %(global.namespace)s or > > whatever you've been calling it. > > Yeah, but as always it's a tradeoff between usability and readability. Wouldn't > that introduce global state? Not really, it's not global state because it's not state. They're constants. I think it would be nice to have an explicit global constant system. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/generate_cc.py:104: c.append(' return false;') On 2012/01/16 04:01:06, calamity wrote: > Clearly this if block is going to grow. On a dev branch I've pulled this into > it's own class that deals with interactions with util.cc. I'm missing the context for this comment. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:116: STRING, FUNDAMENTAL, ARRAY, REF, CHOICES, OBJECT = range(6) On 2012/01/16 04:01:06, calamity wrote: > PropertyType.STRING is unused. On dev branch, FUNDAMENTAL is replaced with > INTEGER, STRING, DOUBLE, BOOLEAN because checking the json_type is dodgy (Should > work as much as possible with code rather than strings). I'm missing the context of this comment.
Looking really good, this will be my last main around of comments, I think. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:84: members actually exist. On 2012/01/13 02:14:09, kalman wrote: > not sure what this sentence means... Ah I see. How about like "This is a union type, check self.type..." http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:38: for tipe in self.__namespace.types.values(): do you actually need "tipe"? From what I can tell, Python handles "type" just fine. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:163: if prop.item_type.json_type == 'string': e.g. when you change the way types are represented, this line would be if prop.item_type.type == PropertyType.STRING etc http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:167: % (var, prop.name)) this line can be on the same as the one above http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:170: (var, prop.name)) line split in the same way as above http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:268: arg = 'const %(type)s& %(name)s' extra space http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/code_test.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/code_test.py:6: import code from code import Code I think for a test it's fine to do that :) http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/code_test.py:8: class TestCode(unittest.TestCase): class CodeTest http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:1: # Copyright (c) 2012 The Chromium Authors. All rights reserved. #!/usr/bin/env python http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:4: We should probably add a general of comment of what this tool is for and how to use it beyond the 'usage' stuff. Mention its history as a tool for generating extension API code. See like tools/coverity/coverity.py for inspiration. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:14: description='Generate C++ boilerplate code for extension apis from json', "Generates a C++ model of a JSON schema" or something. Take out reference to extension APIs. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:15: usage='usage: %prog [options] target referenced_jsons') I think a more unixy way of saying something like this is usage='usage: %prog [option]... schema [referenced_schema]...' http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:28: sys.exit('Error: No input json file') Print usage instead of just "Error.." ? http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:33: target_json = os.path.normpath(args[0]) it's not actually target, that implies output. this is input, so should be "source_schema" or just "schema" (that would match the "usage" line). likewise for all use of "target*" in this file. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:38: # Load type dependencies into the model fullstop http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:57: os.path.relpath(target_json, opts.root), filename_suffix) pull this comment and the os.path.relpath(...) thing into a local variable. also "include path" is confusing to me, implies #include or something, it's just a relative path to the source file right? http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_manager.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_manager.py:9: class CppTypeManager(object): I don't think Manager describes this class properly; it doesn't manage anything (it's not stateful), rather it figures out how to associate types from the model with their C++ representations. Something like CppTypeGenerator would be more appropriate (as I mentioned in a previous comment) http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_manager.py:16: self.namespace = namespace these should all be private http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_manager.py:20: """Translates a json_type into its C++ equivalent. Translates a Property's type into its C++ equivalent. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_util_test.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_util_test.py:8: class TestCppName(unittest.TestCase): class CppUtilTest http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/h_generator.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:47: if includes.render(): seems weird to render() this here then not use the result. how about adding a method like is_empty to Code? http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:93: ) blank line here perhaps? http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:115: (c.eblock() blank line here perhaps? http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:14: def add_namespace(self, json, root_namespace, parent_path, filename_suffix): parent_path is a confusing name, it's the source file right? call it source_file then. also, I don't think that the model should know about the destination filename, that's a concern of the generators, so "filename_suffix" (and "filename") don't quite describe what these are. it's more like the name of the namespace that's being generated (which happens to almost be what files are being generated). So rather than "filename" how about "target_namespace", and instead of "filename_suffix" like "target_namespace_suffix". And for root_namespace, this argument would be unnecessary if it was part of the global string substitution right? I think that would be nicer rather than needing to inject it here; it's not really a concern of the model (particularly since it's the same for all namespaces), but rather an implementation detail of code generation. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:15: """Add a namespace's json to the model. .. "if it has a "compile" property set to true. Returns the new namespace, or None if a namespace wasn't added. """ http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:19: namespace = Namespace(json, root_namespace, extra space. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:34: self.parent_dir, self.parent_filename = os.path.split(parent_path) from what I can tell, this property is unnecessary; where you've used it you can just as logically use parent_path (soon to be called "source_file"). and parent_filename isn't actually needed at all, I think. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:35: self.parent_model = parent_model what's parent_model used for? http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:66: self.param = Property(param['name'], param) yeah using a loop looks a bit strage given the line/comment above. How about something along the lines of parameters = json['parameters'] if len(parameters) == 0: self.param = None elif len(parameters) == 1: param = parameters[0] self.param = Property(param.name, param) else raise AssertionError("callbacks can have at most a single parameter") (I think that an assertion message is probably more useful than a comment.. sorry about that) http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:79: self.callback = Callback(param) assert not self.callback http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:81: self.params.append(Property(param['name'], param)) just put in an else rather than a continue? http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:83: raise KeyError i'm not sure using a KeyError is appropriate? reading about it, it's thrown when you look up a key in a dictionary which isn't there. so it's not quite the same thing. I'd either assert here (with a message), or perhaps we should be defining our own Exception somewhere and throwing those rather than asserting when there are problems with the JSON (well, let's do this in a follow-up patch, if at all). http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:99: self.json_type = json['$ref'] the distinction between "json_type", "item_type", and "type" confuse me, mainly that "json_type" is a pretty ambiguous name. I think the following would be clearer: Have PropertyType enumerate all the types; don't generalise a few under FUNDAMENTAL: class PropertyType(object): BOOLEAN, INTEGER, STRING, DOUBLE, ARRAY, REF, CHOICES, OBJECT = range(8) in the case of what you're calling a "simple type", don't set an extra property at all; the type is entirely defined by the value of type. in the case of ARRAY and OBJECT, do what you're already doing. (then update the comment accordingly.) http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/type_manager_test.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager_test.py:8: import cpp_type_manager from cpp_type_manager import CppTypeManager http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/type_manager_test.py:10: class TestCppTypeManager(unittest.TestCase): file name should be "cpp_type_manager_test.py", and the class name should be "CppTypeManagerTest". http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/util.h (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/util.h:21: // Pushes string of |from|.|name| and into |out|. Returns false if there is no "Adds string of |from|.|name| to |out|. Returns false... http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/util.h:28: // Pushes string of |from|.|name| and into |out|. Returns true on success or ditto http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/util.h:36: // Puts the vector of strings in |from| into a new ListValue at |out|.|name|. "Puts each string in |from|" ... http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/util.h:42: // If from is non-NULL, puts each string in |from| into the |out|.|name|. "If |from| is non-NULL, puts each string $commentFromAbove"
http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:100: Raises type error if passed something that isn't a dict.""" On 2012/01/17 01:59:24, kalman wrote: > On 2012/01/16 04:01:06, calamity wrote: > > On 2012/01/13 02:14:09, kalman wrote: > > > "Raises type error" comment is unnecessary. > > > > The style guide says it should list exceptions it raises? To be honest, these > > should be documented a lot better than they are. > > This isn't really an exception though, it's a programmer error. > > In fact I think it should be an assertion. Done. http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/10004/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:116: STRING, FUNDAMENTAL, ARRAY, REF, CHOICES, OBJECT = range(6) On 2012/01/17 01:59:24, kalman wrote: > On 2012/01/16 04:01:06, calamity wrote: > > PropertyType.STRING is unused. On dev branch, FUNDAMENTAL is replaced with > > INTEGER, STRING, DOUBLE, BOOLEAN because checking the json_type is dodgy > (Should > > work as much as possible with code rather than strings). > > I'm missing the context of this comment. Just a note in case you were wondering why PropertyType.STRING is there. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:38: for tipe in self.__namespace.types.values(): On 2012/01/17 05:42:32, kalman wrote: > do you actually need "tipe"? From what I can tell, Python handles "type" just > fine. I guess.. but that's confusing? type is a built in function and assigning type won't go out of scope until end of function. If somebody wants to use type() (for debugging for instance) they'll have to figure out what the hell happened. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:163: if prop.item_type.json_type == 'string': On 2012/01/17 05:42:32, kalman wrote: > e.g. when you change the way types are represented, this line would be > > if prop.item_type.type == PropertyType.STRING > > etc Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:167: % (var, prop.name)) On 2012/01/17 05:42:32, kalman wrote: > this line can be on the same as the one above Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:268: arg = 'const %(type)s& %(name)s' On 2012/01/17 05:42:32, kalman wrote: > extra space Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/code_test.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/code_test.py:6: import code On 2012/01/17 05:42:32, kalman wrote: > from code import Code > > I think for a test it's fine to do that :) Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/code_test.py:8: class TestCode(unittest.TestCase): On 2012/01/17 05:42:32, kalman wrote: > class CodeTest Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:1: # Copyright (c) 2012 The Chromium Authors. All rights reserved. On 2012/01/17 05:42:32, kalman wrote: > #!/usr/bin/env python Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:4: On 2012/01/17 05:42:32, kalman wrote: > We should probably add a general of comment of what this tool is for and how to > use it beyond the 'usage' stuff. Mention its history as a tool for generating > extension API code. > > See like tools/coverity/coverity.py for inspiration. Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:14: description='Generate C++ boilerplate code for extension apis from json', On 2012/01/17 05:42:32, kalman wrote: > "Generates a C++ model of a JSON schema" or something. Take out reference to > extension APIs. Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:15: usage='usage: %prog [options] target referenced_jsons') On 2012/01/17 05:42:32, kalman wrote: > I think a more unixy way of saying something like this is > > usage='usage: %prog [option]... schema [referenced_schema]...' > Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:28: sys.exit('Error: No input json file') On 2012/01/17 05:42:32, kalman wrote: > Print usage instead of just "Error.." ? Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:38: # Load type dependencies into the model On 2012/01/17 05:42:32, kalman wrote: > fullstop Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:57: os.path.relpath(target_json, opts.root), filename_suffix) On 2012/01/17 05:42:32, kalman wrote: > pull this comment and the os.path.relpath(...) thing into a local variable. > also "include path" is confusing to me, implies #include or something, it's just > a relative path to the source file right? Include path is the #include path? The relative path from src is being used as the #include path to the file. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:57: os.path.relpath(target_json, opts.root), filename_suffix) On 2012/01/17 05:42:32, kalman wrote: > pull this comment and the os.path.relpath(...) thing into a local variable. > also "include path" is confusing to me, implies #include or something, it's just > a relative path to the source file right? Well, it's the output path here, but the #include path for the referenced jsons... http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/h_generator.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:47: if includes.render(): On 2012/01/17 05:42:32, kalman wrote: > seems weird to render() this here then not use the result. how about adding a > method like is_empty to Code? Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:93: ) On 2012/01/17 05:42:32, kalman wrote: > blank line here perhaps? Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:115: (c.eblock() On 2012/01/17 05:42:32, kalman wrote: > blank line here perhaps? Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:14: def add_namespace(self, json, root_namespace, parent_path, filename_suffix): On 2012/01/17 05:42:32, kalman wrote: > parent_path is a confusing name, it's the source file right? call it > source_file then. > > also, I don't think that the model should know about the destination filename, > that's a concern of the generators, so "filename_suffix" (and "filename") don't > quite describe what these are. it's more like the name of the namespace that's > being generated (which happens to almost be what files are being generated). So > rather than "filename" how about "target_namespace", and instead of > "filename_suffix" like "target_namespace_suffix". > > And for root_namespace, this argument would be unnecessary if it was part of the > global string substitution right? I think that would be nicer rather than > needing to inject it here; it's not really a concern of the model (particularly > since it's the same for all namespaces), but rather an implementation detail of > code generation. I'm a little iffy with global substitution because it's not clear where things are defined. In particular, the root namespace is set once but has to be substituted in every Code object. That's at odds with the current safety check (don't add Code objects if there's anything unsubstituted). I could change the whole generator to use one object but that Code object will become bigger and clunkier. Alternatively I could remove the safety check and do the substitution at Code.concat time. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:15: """Add a namespace's json to the model. On 2012/01/17 05:42:32, kalman wrote: > .. "if it has a "compile" property set to true. > Returns the new namespace, or None if a namespace wasn't added. > """ Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:19: namespace = Namespace(json, root_namespace, On 2012/01/17 05:42:32, kalman wrote: > extra space. Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:35: self.parent_model = parent_model On 2012/01/17 05:42:32, kalman wrote: > what's parent_model used for? Removed. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:66: self.param = Property(param['name'], param) On 2012/01/17 05:42:32, kalman wrote: > yeah using a loop looks a bit strage given the line/comment above. How about > something along the lines of > > parameters = json['parameters'] > if len(parameters) == 0: > self.param = None > elif len(parameters) == 1: > param = parameters[0] > self.param = Property(param.name, param) > else > raise AssertionError("callbacks can have at most a single parameter") > > (I think that an assertion message is probably more useful than a comment.. > sorry about that) Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:79: self.callback = Callback(param) On 2012/01/17 05:42:32, kalman wrote: > assert not self.callback Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:81: self.params.append(Property(param['name'], param)) On 2012/01/17 05:42:32, kalman wrote: > just put in an else rather than a continue? Done. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:83: raise KeyError On 2012/01/17 05:42:32, kalman wrote: > i'm not sure using a KeyError is appropriate? reading about it, it's thrown > when you look up a key in a dictionary which isn't there. so it's not quite the > same thing. > > I'd either assert here (with a message), or perhaps we should be defining our > own Exception somewhere and throwing those rather than asserting when there are > problems with the JSON (well, let's do this in a follow-up patch, if at all). Agreed. Left this as an AssertionError for now. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:99: self.json_type = json['$ref'] On 2012/01/17 05:42:32, kalman wrote: > the distinction between "json_type", "item_type", and "type" confuse me, mainly > that "json_type" is a pretty ambiguous name. > > I think the following would be clearer: > > Have PropertyType enumerate all the types; don't generalise a few under > FUNDAMENTAL: > > class PropertyType(object): > BOOLEAN, INTEGER, STRING, DOUBLE, ARRAY, REF, CHOICES, OBJECT = range(8) > > in the case of what you're calling a "simple type", don't set an extra property > at all; the type is entirely defined by the value of type. > > in the case of ARRAY and OBJECT, do what you're already doing. > > (then update the comment accordingly.) Agreed. That's what the comment I made last revision was saying.
LGTM after you fix up those few things. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:38: for tipe in self.__namespace.types.values(): On 2012/01/18 05:43:08, calamity wrote: > On 2012/01/17 05:42:32, kalman wrote: > > do you actually need "tipe"? From what I can tell, Python handles "type" just > > fine. > > I guess.. but that's confusing? type is a built in function and assigning type > won't go out of scope until end of function. If somebody wants to use type() > (for debugging for instance) they'll have to figure out what the hell happened. > > Ah right. I only noted this because you have a property "type" on some of the model objects, but that makes sense. Cool. http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/21001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:57: os.path.relpath(target_json, opts.root), filename_suffix) On 2012/01/18 05:43:08, calamity wrote: > On 2012/01/17 05:42:32, kalman wrote: > > pull this comment and the os.path.relpath(...) thing into a local variable. > > also "include path" is confusing to me, implies #include or something, it's > just > > a relative path to the source file right? > > Well, it's the output path here, but the #include path for the referenced > jsons... Cool, this can be 1 line now? Also, comment above needs a fullstop. http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:127: c.append('if(!dict->%s)' % cpp_util.get_fundamental_value(prop, space between "if" and "(" http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:162: if PropertyType.is_fundamental(prop): perhaps it would be more idiomatic to have is_fundamental be a method on PropertyType if prop.type.is_fundamental(): ... http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:246: c.append('if(!%(ctype)s::Populate(*%(name)s_param, &out->%(name)s))') space been "if" and "(" http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:27: return bool(self.__code) newline after this http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:43: cpp_type = simple_c_types[prop.type] Just be explicit, and don't have the simple_c_types thing. It's less magical. if prop.type == PropertyType.BOOLEAN cpp_type == 'bool' elif prop.type == PropertyType.INTEGER cpp_type == 'int' ... http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:109: self.type = fundamental_types[json_type] ditto: be explicit, don't have fundamental_types http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:127: INTEGER, DOUBLE, BOOLEAN, STRING, ARRAY, REF, CHOICES, OBJECT = range(8) sorry to keep on messing with you here, but it seems like a safer way to express this would be like class PropertyType: class Info: def __init__(self, is_fundamental): self.is_fundamental = is_fundamental INTEGER = Info(True) DOUBLE = Info(True) ... OBJECT = Info(False) which would be a Java-style enum. all the other code would work the same way, except now you can say property.type.is_fundamental rather than PropertyType.is_fundamental(prop) and I hate static methods and like instance methods, so that's a nice thing. and that also opens up possibilities for putting other things on the object, if necessary. http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:130: def is_fundamental(prop): comment above notwithstanding, I kind of regret saying it because it seems like overkill at this point. in any case, certainly, if this method should exist at all it should take a type not a property, since the method is in PropertyType.
http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:43: cpp_type = simple_c_types[prop.type] On 2012/01/18 06:57:28, kalman wrote: > Just be explicit, and don't have the simple_c_types thing. It's less magical. > > if prop.type == PropertyType.BOOLEAN > cpp_type == 'bool' > elif prop.type == PropertyType.INTEGER > cpp_type == 'int' > ... Are you adverse to the python-style switch case? cpp_type = { PropertyType.BOOLEAN: 'bool', PropertyType.INTEGER: 'int', PropertyType.DOUBLE: 'double', PropertyType.STRING: 'std::string', }[prop.type]
http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:43: cpp_type = simple_c_types[prop.type] On 2012/01/18 07:30:54, calamity wrote: > On 2012/01/18 06:57:28, kalman wrote: > > Just be explicit, and don't have the simple_c_types thing. It's less magical. > > > > if prop.type == PropertyType.BOOLEAN > > cpp_type == 'bool' > > elif prop.type == PropertyType.INTEGER > > cpp_type == 'int' > > ... > > Are you adverse to the python-style switch case? > > cpp_type = { > PropertyType.BOOLEAN: 'bool', > PropertyType.INTEGER: 'int', > PropertyType.DOUBLE: 'double', > PropertyType.STRING: 'std::string', > }[prop.type] No, though then you'd also need to have PropertyType.ARRAY: 'std::vector<%s>' to be consistent. However... I believe that that won't work if you make BOOLEAN/INTEGER/etc dictionaries rather than ints.
http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:127: c.append('if(!dict->%s)' % cpp_util.get_fundamental_value(prop, On 2012/01/18 06:57:28, kalman wrote: > space between "if" and "(" Done. http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:162: if PropertyType.is_fundamental(prop): On 2012/01/18 06:57:28, kalman wrote: > perhaps it would be more idiomatic to have is_fundamental be a method on > PropertyType > > if prop.type.is_fundamental(): > ... Done. http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:27: return bool(self.__code) On 2012/01/18 06:57:28, kalman wrote: > newline after this Done. http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:43: cpp_type = simple_c_types[prop.type] On 2012/01/18 07:49:37, kalman wrote: > On 2012/01/18 07:30:54, calamity wrote: > > On 2012/01/18 06:57:28, kalman wrote: > > > Just be explicit, and don't have the simple_c_types thing. It's less > magical. > > > > > > if prop.type == PropertyType.BOOLEAN > > > cpp_type == 'bool' > > > elif prop.type == PropertyType.INTEGER > > > cpp_type == 'int' > > > ... > > > > Are you adverse to the python-style switch case? > > > > cpp_type = { > > PropertyType.BOOLEAN: 'bool', > > PropertyType.INTEGER: 'int', > > PropertyType.DOUBLE: 'double', > > PropertyType.STRING: 'std::string', > > }[prop.type] > > No, though then you'd also need to have PropertyType.ARRAY: 'std::vector<%s>' to > be consistent. > > However... I believe that that won't work if you make BOOLEAN/INTEGER/etc > dictionaries rather than ints. Apparently you can use your classes as keys of a dict. But I guess I'll stick with elifs for readability. http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:109: self.type = fundamental_types[json_type] On 2012/01/18 06:57:28, kalman wrote: > ditto: be explicit, don't have fundamental_types Done. http://codereview.chromium.org/9114036/diff/21002/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:127: INTEGER, DOUBLE, BOOLEAN, STRING, ARRAY, REF, CHOICES, OBJECT = range(8) On 2012/01/18 06:57:28, kalman wrote: > sorry to keep on messing with you here, but it seems like a safer way to express > this would be like > > class PropertyType: > class Info: > def __init__(self, is_fundamental): > self.is_fundamental = is_fundamental > > INTEGER = Info(True) > DOUBLE = Info(True) > ... > OBJECT = Info(False) > > which would be a Java-style enum. > > all the other code would work the same way, except now you can say > > property.type.is_fundamental rather than PropertyType.is_fundamental(prop) > > and I hate static methods and like instance methods, so that's a nice thing. > and that also opens up possibilities for putting other things on the object, if > necessary. Done.
This is a python tool that generates C++ code from the api json files at build time. The code is mostly conversion to and from base::Values. The main executable is tools/json_schema_compiler/compiler.py. cc_generator and h_generator are the main code generation classes. Example generated code for the permissions extensions api is also included and example usage is provided in extension_permissions_api*. @yoz - please review the python code and integration with extensions @thakis - please check the build changes are acceptable @aa - please double check the effect on extensions Thanks
The gyp files look like a very good start! I'll leave it up to aa if the CL as such makes sense (it adds a lot of code for the generator, I don't know how much can be deleted once it's in. Also, metaprogramming makes it easy to generate bloaty code, makes the generated code hard to debug, etc, so I'm generally not a fan.) http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.gypi File build/json_schema_compile.gypi (right): http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:10: 'rules': [ It looks like this rule requires a few variables to be set to be useful. Is there a way to prevent that? For example, for --destdir, why can't you use <(INTERMEDIATE_DIR) (or, if you need these files from multiple targets – which you probably dont – <(SHARED_INTERMEDIATE_DIR)? If you can't get rid of all variables, maybe you can add a comment that lists all variables that need to be set and what they mean? (Kind of like a python function pydoc string) http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:34: '<@(json_schema_files)', Why do you need to pass in both <(RULE_INPUT_PATH) and <@(json_schema_files)? As far as I understand, a rule is something that says "For files with this 'extension', run the following command, to produce the files in 'outputs'". The input file is set to <(RULE_INPUT_PATH), so where you include this both <(RULE_INPUT_PATH) and <@(json_schema_files) should be the same file (?) http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:64: api_defs = json.loads(schema_file.read()) with open(schema, 'r') as schema_file: api_defs = json.load(schema_file) ?
http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.gypi File build/json_schema_compile.gypi (right): http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:10: 'rules': [ On 2012/01/18 17:30:12, Nico wrote: > It looks like this rule requires a few variables to be set to be useful. Is > there a way to prevent that? > > For example, for --destdir, why can't you use <(INTERMEDIATE_DIR) (or, if you > need these files from multiple targets – which you probably dont > – <(SHARED_INTERMEDIATE_DIR)? > > If you can't get rid of all variables, maybe you can add a comment that lists > all variables that need to be set and what they mean? (Kind of like a python > function pydoc string) Yeah, using <(SHARED_INTERMEDIATE_DIR) instead of <(cc_root) works. I wasn't totally sure what I was doing here so most of it was just taking cues from build/protoc.gypi. I could get rid of <(cc_dir) if there's a variable that represents the path to the directory that the RULE_INPUT file is in. Is there anything like that? http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:34: '<@(json_schema_files)', On 2012/01/18 17:30:12, Nico wrote: > Why do you need to pass in both <(RULE_INPUT_PATH) and <@(json_schema_files)? > > As far as I understand, a rule is something that says "For files with this > 'extension', run the following command, to produce the files in 'outputs'". The > input file is set to <(RULE_INPUT_PATH), so where you include this both > <(RULE_INPUT_PATH) and <@(json_schema_files) should be the same file (?) This was a bit of a hack. Each json could have references to other jsons. So the <(RULE_INPUT_PATH) is the json we're currently generating which outputs <(RULE_INPUT_ROOT)_api.cc/h. The <@(json_schema_files) are all the jsons that comprise the model to ensure dependencies are able to be resolved.
http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.gypi File build/json_schema_compile.gypi (right): http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:10: 'rules': [ > I could get rid of <(cc_dir) if there's a variable that represents the path to > the directory that the RULE_INPUT file is in. Is there anything like that? Does RULE_INPUT_DIRNAME work? http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:34: '<@(json_schema_files)', On 2012/01/18 23:46:18, calamity wrote: > On 2012/01/18 17:30:12, Nico wrote: > > Why do you need to pass in both <(RULE_INPUT_PATH) and <@(json_schema_files)? > > > > As far as I understand, a rule is something that says "For files with this > > 'extension', run the following command, to produce the files in 'outputs'". > The > > input file is set to <(RULE_INPUT_PATH), so where you include this both > > <(RULE_INPUT_PATH) and <@(json_schema_files) should be the same file (?) > > This was a bit of a hack. Each json could have references to other jsons. So the > <(RULE_INPUT_PATH) is the json we're currently generating which outputs > <(RULE_INPUT_ROOT)_api.cc/h. The <@(json_schema_files) are all the jsons that > comprise the model to ensure dependencies are able to be resolved. I see. And you can't just put the dependencies between the json files into the json files itself, because gyp needs to know about them to rebuild stuff correctly. Ok, then keeping this as is and mentioning them in a "how to use this rule" comment at the top is fine.
http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.gypi File build/json_schema_compile.gypi (right): http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:10: 'rules': [ On 2012/01/18 23:54:42, Nico wrote: > > I could get rid of <(cc_dir) if there's a variable that represents the path to > > the directory that the RULE_INPUT file is in. Is there anything like that? > > Does RULE_INPUT_DIRNAME work? I've looked at the tests for RULE_INPUT_DIRNAME and it really looks like it should work. But it doesn't. It ends up substituting with nothing.
> I've looked at the tests for RULE_INPUT_DIRNAME and it really looks like it > should work. But it doesn't. It ends up substituting with nothing. :-( Which gyp generator are you testing this with? msvs?
On 2012/01/19 00:41:12, Nico wrote: > > I've looked at the tests for RULE_INPUT_DIRNAME and it really looks like it > > should work. But it doesn't. It ends up substituting with nothing. > > :-( > > Which gyp generator are you testing this with? msvs? I'm using make. I think the reason it substitutes to nothing is because it's taking relative path from the gyp which is nothing in this case.
http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.gypi File build/json_schema_compile.gypi (right): http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:10: 'rules': [ > I've looked at the tests for RULE_INPUT_DIRNAME and it really looks like it > should work. But it doesn't. It ends up substituting with nothing. Might be a bug in gyp. Taking a step back: What do you need this for? To make the outputs not collide in SHARED_INTERMEDIATE_DIR? Does just using INTERMEDIATE_DIR (which exists for this very use case) not work?
http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.gypi File build/json_schema_compile.gypi (right): http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:10: 'rules': [ On 2012/01/19 00:49:46, Nico wrote: > > I've looked at the tests for RULE_INPUT_DIRNAME and it really looks like it > > should work. But it doesn't. It ends up substituting with nothing. > > Might be a bug in gyp. > > Taking a step back: What do you need this for? To make the outputs not collide > in SHARED_INTERMEDIATE_DIR? Does just using INTERMEDIATE_DIR (which exists for > this very use case) not work? When I use INTERMEDIATE_DIR, the generated files aren't picked up by the the .cc files in chrome_browser.gypi.
> When I use INTERMEDIATE_DIR, the generated files aren't picked up by the the .cc > files in chrome_browser.gypi. Ok, we tried. Please add that variable to the "how to use" comment as well, then. Thanks for humoring me.
I'm not that familiar with the permissions API; jstritar would best be able to review those changes. Here's my preliminary review of the Python. I have nothing major, just a lot of style comments. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.h (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.h:25: // Converts the |permissions| to a new permission set. Returns NULL if the What do you mean by "new" permission set? http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.h (right): http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:83: struct Params { Can this be omitted? http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:10: class CCGenerator(object): General comment: have a read through the style guide for Python. http://www.chromium.org/developers/coding-style http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:60: def __generate_type(self, tipe): type_ is preferred over tipe. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:188: else: This also doesn't handle single properties, right? (like the TODO above) http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:241: c.append('// TODO Needs some sort of casting') Seems like you could raise NotImplementedError here and elsewhere you are generating TODOs. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:8: Logically each object should be a block of code. All methods except |render| render and is_empty, apparently. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:12: self.__code = [] I think one underscore is more typical. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:15: self.__comment_length = comment_length I feel like this variable should have "wrap" in its name. Although, why wrap comments? I suppose I don't understand whether any human will read the generated code. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:17: def append(self, line=''): The Python style is to name things like Append and IsEmpty. See http://www.chromium.org/developers/coding-style. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:104: 'Named arguments only. Use %%s to escape') Indent to paren. Missing a space between the first 2 sentences, and a period at the end. "%s" is confusing as a plural of "%" in this context, isn't it? http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:18: import model Imports should be sorted. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:39: (opts, args) = parser.parse_args() Looks like you want most of this file to be behind a __name__ == '__main__' check. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:80: namespace.target_namespace + '.cc'), 'w') Is this going to put experimental APIs into files named like experimental.webNavigation.cc? You might also consider using the with/as pattern that thakis described above. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:37: cpp_type = 'bool' too many spaces http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:45: cpp_type = 'std::vector<%s>' % self.get_type(prop.item_type) Did you mean to call it with pad_for_generics=True? http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:74: includes.append('#include "%s/%s.h"' % ( If you had 2 dependencies from the same namespace, could you end up with a duplicate #include? http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_util.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_util.py:20: def cpp_name(s): Separate top-level function and class definitions with two blank lines. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_util.py:27: return '_'.join([x[0].upper() + x[1:] for x in s.split('.')]) x.capitalize() http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/h_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:48: if includes.is_empty(): This looks incorrect. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:76: .append('} // namespace %s' % self.__root_namespace) 2 spaces before inline comments http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:8: """Model of the API. This is a little vague. What API is it modeling? The entire API? http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:16: to true. Returns the new namespace or None if a namespac wasn't added. typo: namespac http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:22: for tipe in namespace.types.values(): type_ is better than tipe. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:66: raise AssertionError("Callbacks can have at most a single parameter") Where does this constraint come from? http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:103: self.type = PropertyType.STRING I think even though you can name an attribute the same as a reserved word, it's not recommended. Use type_. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/model_test.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model_test.py:26: self.assertEquals(len(self.model.namespaces), 3) Expected value comes first.
Here are a few more interesting comments. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:50: EXTENSION_FUNCTION_VALIDATE(Contains::Params::Populate(*args_, ¶ms)); Should these all be *args_.get()? http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers_unittest.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers_unittest.cc:64: ASSERT_TRUE(UnpackPermissionSet( This file looks like it needs more changes than just this. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/h_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:146: c.sblock('struct Params {') Seems like this should be inside the if function.params: block. (This gets to my comment on the generated empty Params in the .h file.) General comment: there seems to be some common logic between the .h generator and the .cc generator (e.g. you'd declare a function in the .h iff you define it in the .cc). Is there a way you could unify the logic so it didn't need to be duplicated? http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/util.cc (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/util.cc:46: out->reset(new std::vector<std::string>()); This clears out, whereas the comment says that it appends to out.
In general: hooray. I'm dragging my feet on the Python review, hoping that Yoyo will do it :) http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.gypi File build/json_schema_compile.gypi (right): http://codereview.chromium.org/9114036/diff/36003/build/json_schema_compile.g... build/json_schema_compile.gypi:1: # Copyright (c) 2011 The Chromium Authors. All rights reserved. I know next to nothing about gyp, so I'm going to ignore this. Nico seems like he's on top of it. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:21: using extensions::permissions_api::Contains; Maybe extensions::api::permissions::Contains? Only one character longer, and cooler! http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.cc:80: return new ExtensionPermissionSet(apis, origins, URLPatternSet()); I agree with Yoyo's comment in the header: The comments/name should make it more clear that this will create a new object that the caller must take ownership of. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.h (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.h:17: namespace permissions_api { Maybe you should reserve api::<name> for generated code? That way names won't conflict. This could just be part of extensions namespace. http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.h (right): http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:43: static bool Populate(const Value& value, Permissions* out); It seems like it would be more natural to have this be: // Creates a Permissions object from the specified Value. // Returns NULL for failure. static Permissions* Create(const Value& value); Same for the other structs. http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:57: struct Contains { Can anything else go in Contains? If not, it is a namespace, not a struct.
Did a bit of rework. I just thought I'd clean up the style first and do some refactoring to make it easier to read. Let me know where else the style needs touching up. If you were wondering why the style was so off, it was because I followed the google style guide instead of the chromium one. Oops. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:21: using extensions::permissions_api::Contains; On 2012/01/19 23:31:13, Aaron Boodman wrote: > Maybe extensions::api::permissions::Contains? Only one character longer, and > cooler! Would we need to change that namespace structure anywhere else? http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.cc:80: return new ExtensionPermissionSet(apis, origins, URLPatternSet()); On 2012/01/19 23:31:13, Aaron Boodman wrote: > I agree with Yoyo's comment in the header: The comments/name should make it more > clear that this will create a new object that the caller must take ownership of. Done. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.h (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.h:25: // Converts the |permissions| to a new permission set. Returns NULL if the On 2012/01/19 02:19:40, Yoyo Zhou wrote: > What do you mean by "new" permission set? In the sense that the function creates the ExtensionPermissionSet. http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.h (right): http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:83: struct Params { On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Can this be omitted? Yeah, it was being generated for consistency. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:60: def __generate_type(self, tipe): On 2012/01/19 02:19:40, Yoyo Zhou wrote: > type_ is preferred over tipe. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:188: else: On 2012/01/19 02:19:40, Yoyo Zhou wrote: > This also doesn't handle single properties, right? (like the TODO above) fundamental types and REF types are the single properties. I should make the TODO more clear I guess. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:8: Logically each object should be a block of code. All methods except |render| On 2012/01/19 02:19:40, Yoyo Zhou wrote: > render and is_empty, apparently. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:12: self.__code = [] On 2012/01/19 02:19:40, Yoyo Zhou wrote: > I think one underscore is more typical. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:15: self.__comment_length = comment_length On 2012/01/19 02:19:40, Yoyo Zhou wrote: > I feel like this variable should have "wrap" in its name. > > Although, why wrap comments? I suppose I don't understand whether any human will > read the generated code. Since the tool is standalone, it may be used to generate classes that aren't necessarily side effects of a build. Also, this would be useful for debugging (both code using the generated code and the generator itself) and checking interface conformance. I don't think it hurts to make it readable. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:17: def append(self, line=''): On 2012/01/19 02:19:40, Yoyo Zhou wrote: > The Python style is to name things like Append and IsEmpty. See > http://www.chromium.org/developers/coding-style. Ah, I was following http://google-styleguide.googlecode.com/svn/trunk/pyguide.html http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:104: 'Named arguments only. Use %%s to escape') On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Indent to paren. Missing a space between the first 2 sentences, and a period at > the end. "%s" is confusing as a plural of "%" in this context, isn't it? Done. Added quotes around %s and %r to be clearer. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:39: (opts, args) = parser.parse_args() On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Looks like you want most of this file to be behind a __name__ == '__main__' > check. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:64: api_defs = json.loads(schema_file.read()) On 2012/01/18 17:30:12, Nico wrote: > with open(schema, 'r') as schema_file: > api_defs = json.load(schema_file) > > ? Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:80: namespace.target_namespace + '.cc'), 'w') On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Is this going to put experimental APIs into files named like > experimental.webNavigation.cc? > > You might also consider using the with/as pattern that thakis described above. Hmm. Good point. Refactored this whole thing a bit. The model shouldn't have dealt with the namespace name. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:37: cpp_type = 'bool' On 2012/01/19 02:19:40, Yoyo Zhou wrote: > too many spaces Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:45: cpp_type = 'std::vector<%s>' % self.get_type(prop.item_type) On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Did you mean to call it with pad_for_generics=True? Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:74: includes.append('#include "%s/%s.h"' % ( On 2012/01/19 02:19:40, Yoyo Zhou wrote: > If you had 2 dependencies from the same namespace, could you end up with a > duplicate #include? Fixed and added a test. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_util.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_util.py:20: def cpp_name(s): On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Separate top-level function and class definitions with two blank lines. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_util.py:27: return '_'.join([x[0].upper() + x[1:] for x in s.split('.')]) On 2012/01/19 02:19:40, Yoyo Zhou wrote: > x.capitalize() Capitalize inconveniently lowercases everything after the 1st letter. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/h_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:48: if includes.is_empty(): On 2012/01/19 02:19:40, Yoyo Zhou wrote: > This looks incorrect. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:76: .append('} // namespace %s' % self.__root_namespace) On 2012/01/19 02:19:40, Yoyo Zhou wrote: > 2 spaces before inline comments Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:146: c.sblock('struct Params {') On 2012/01/19 23:19:11, Yoyo Zhou wrote: > Seems like this should be inside the > if function.params: > block. (This gets to my comment on the generated empty Params in the .h file.) > > General comment: there seems to be some common logic between the .h generator > and the .cc generator (e.g. you'd declare a function in the .h iff you define it > in the .cc). Is there a way you could unify the logic so it didn't need to be > duplicated? Originally, I had one class that generated the .cc and .h which allowed for unified logic. I changed it because I received feedback that it unclear exactly where code was coming from and where it was going. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/model.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:8: """Model of the API. On 2012/01/19 02:19:40, Yoyo Zhou wrote: > This is a little vague. What API is it modeling? The entire API? Comment has been changed. Still not sure if it's descriptive enough. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:16: to true. Returns the new namespace or None if a namespac wasn't added. On 2012/01/19 02:19:40, Yoyo Zhou wrote: > typo: namespac Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:22: for tipe in namespace.types.values(): On 2012/01/19 02:19:40, Yoyo Zhou wrote: > type_ is better than tipe. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:66: raise AssertionError("Callbacks can have at most a single parameter") On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Where does this constraint come from? I believe it's just how the extensions api system is designed? If this generator is used for anything else, it might be useful to get any constraints like this from say, a json schema. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model.py:103: self.type = PropertyType.STRING On 2012/01/19 02:19:40, Yoyo Zhou wrote: > I think even though you can name an attribute the same as a reserved word, it's > not recommended. Use type_. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/model_test.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/model_test.py:26: self.assertEquals(len(self.model.namespaces), 3) On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Expected value comes first. Done.
Uploaded another patch which hopefully addresses the most of the remaining issues. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:50: EXTENSION_FUNCTION_VALIDATE(Contains::Params::Populate(*args_, ¶ms)); On 2012/01/19 23:19:11, Yoyo Zhou wrote: > Should these all be *args_.get()? From what I understand of operator overloading I think the implementations in base/values.h are equivalent. I'm changing it to *args_ because it's more concise. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.h (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.h:17: namespace permissions_api { On 2012/01/19 23:31:13, Aaron Boodman wrote: > Maybe you should reserve api::<name> for generated code? That way names won't > conflict. This could just be part of extensions namespace. Done. http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers_unittest.cc (right): http://codereview.chromium.org/9114036/diff/36003/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers_unittest.cc:64: ASSERT_TRUE(UnpackPermissionSet( On 2012/01/19 23:19:11, Yoyo Zhou wrote: > This file looks like it needs more changes than just this. Done. http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.h (right): http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:43: static bool Populate(const Value& value, Permissions* out); On 2012/01/19 23:31:13, Aaron Boodman wrote: > It seems like it would be more natural to have this be: > > // Creates a Permissions object from the specified Value. > // Returns NULL for failure. > static Permissions* Create(const Value& value); > > Same for the other structs. One problem that may arise is that Creating for members inside structs becomes more painful. Currently you can use Permissions::Populate(*args_, &var.permissions). Using Create would necessitate either copy operators or changing all members into scoped_ptrs which we currently use to indicate that members are optional. Create looks nice for Params objects since they need to be declared explicitly in the use cases I can think of. For types, having a populate would probably be nicer within the generated classes where it's used as a member. I've changed it to Create for Params. http://codereview.chromium.org/9114036/diff/36003/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:57: struct Contains { On 2012/01/19 23:31:13, Aaron Boodman wrote: > Can anything else go in Contains? If not, it is a namespace, not a struct. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:241: c.append('// TODO Needs some sort of casting') On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Seems like you could raise NotImplementedError here and elsewhere you are > generating TODOs. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:18: import model On 2012/01/19 02:19:40, Yoyo Zhou wrote: > Imports should be sorted. Done. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/util.cc (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/util.cc:46: out->reset(new std::vector<std::string>()); On 2012/01/19 23:19:11, Yoyo Zhou wrote: > This clears out, whereas the comment says that it appends to out. Done.
nice! http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:23: nit: no new line? http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.cc:43: } nit: no { } for the blocks containing 1 line http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.cc:51: if (permissions.permissions.get()) { nit: the for loop might be more compact if you assign this to a variable... up to you http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.h (right): http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:72: class Result { Are you planning on updating the permission functions to use the Result classes? http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/h_generator.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:114: ' serialized form of this %(classname)s object.') I think you should add a note to the comment saying it passes ownership to the caller.
Looking pretty good, a few more comments here and there. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:15: self.__comment_length = comment_length On 2012/01/20 01:10:25, calamity wrote: > On 2012/01/19 02:19:40, Yoyo Zhou wrote: > > I feel like this variable should have "wrap" in its name. > > > > Although, why wrap comments? I suppose I don't understand whether any human > will > > read the generated code. > > Since the tool is standalone, it may be used to generate classes that aren't > necessarily side effects of a build. Also, this would be useful for debugging > (both code using the generated code and the generator itself) and checking > interface conformance. I don't think it hurts to make it readable. Ah, I see. That seems fine then. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:17: def append(self, line=''): On 2012/01/20 01:10:25, calamity wrote: > On 2012/01/19 02:19:40, Yoyo Zhou wrote: > > The Python style is to name things like Append and IsEmpty. See > > http://www.chromium.org/developers/coding-style. > > Ah, I was following > http://google-styleguide.googlecode.com/svn/trunk/pyguide.html Function names should start with a capital. http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_util.py (right): http://codereview.chromium.org/9114036/diff/36003/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_util.py:27: return '_'.join([x[0].upper() + x[1:] for x in s.split('.')]) On 2012/01/20 01:10:25, calamity wrote: > On 2012/01/19 02:19:40, Yoyo Zhou wrote: > > x.capitalize() > > Capitalize inconveniently lowercases everything after the 1st letter. Oh, sadness. http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:48: Contains::Params* params(Contains::Params::Create(*args_)); You probably want scoped_ptr<Contains::Params>, or else params will leak. (Same below.) http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.cc:1: // Copyright (c) 2012 The Chromium Authors. All rights reserved. This doesn't look like the updated version (no Params::Create as far as I can tell). Can you upload it? http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:7: import cpp_type_generator Looks like you're not using this import. (Same in h_generator.) I got confused because it shares a name with an argument to __init__. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:19: def generate(self): Method names should start with caps. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:90: # TODO(calamity): this handle single PropertyType.REF properties. This comment seems incomplete. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:123: elif proptype_.is_fundamental: prop.type_? http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:135: def _generateTypeTovalue(self, type_): ToValue http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:232: c.append('scoped_ptr<Params> out;') Should this be outside the for loop? Why not use a regular pointer for out instead of a scoped_ptr, since the caller of Params::Create has to take ownership anyways? out doesn't seem to be allocated. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:53: Stray newline? http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:105: 'Named arguments only. Use %%s to escape') I still read this as use '%s' to escape, rather than use '%'s to escape. Is that right? You could just write: use '%' to escape. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:31: description='Generates a C++ model of an API from JSON schema', nit: descriptions should end with period. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:76: continue This looks like it should be above the out_file = ... http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:101: print '%s.cc\n' % out_file nit: extra \n http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:21: self._root_namespace = root_namespace.split('::') This always works, so you don't need the if clause. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:32: self._types[type_] = namespace _types should have a more descriptive name, such as type_namespaces.
Updated to HEAD, did a bit of rework and utilized Function::Result where possible. Some function return types were changed to scoped_ptr on kalman's suggestion because it would provide extra safety. http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:23: On 2012/01/23 22:42:07, jstritar wrote: > nit: no new line? Done. http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api.cc:48: Contains::Params* params(Contains::Params::Create(*args_)); On 2012/01/23 23:16:42, Yoyo Zhou wrote: > You probably want scoped_ptr<Contains::Params>, or else params will leak. (Same > below.) Done. http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... File chrome/browser/extensions/extension_permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.cc:43: } On 2012/01/23 22:42:07, jstritar wrote: > nit: no { } for the blocks containing 1 line Done. http://codereview.chromium.org/9114036/diff/45001/chrome/browser/extensions/e... chrome/browser/extensions/extension_permissions_api_helpers.cc:51: if (permissions.permissions.get()) { On 2012/01/23 22:42:07, jstritar wrote: > nit: the for loop might be more compact if you assign this to a variable... up > to you Done. http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.cc (right): http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.cc:1: // Copyright (c) 2012 The Chromium Authors. All rights reserved. On 2012/01/23 23:16:42, Yoyo Zhou wrote: > This doesn't look like the updated version (no Params::Create as far as I can > tell). Can you upload it? Done. http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... File generated_files_will_not_submit/permissions_api.h (right): http://codereview.chromium.org/9114036/diff/45001/generated_files_will_not_su... generated_files_will_not_submit/permissions_api.h:72: class Result { On 2012/01/23 22:42:07, jstritar wrote: > Are you planning on updating the permission functions to use the Result classes? Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:7: import cpp_type_generator On 2012/01/23 23:16:42, Yoyo Zhou wrote: > Looks like you're not using this import. (Same in h_generator.) I got confused > because it shares a name with an argument to __init__. Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:19: def generate(self): On 2012/01/23 23:16:42, Yoyo Zhou wrote: > Method names should start with caps. Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:90: # TODO(calamity): this handle single PropertyType.REF properties. On 2012/01/23 23:16:42, Yoyo Zhou wrote: > This comment seems incomplete. Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:123: elif proptype_.is_fundamental: On 2012/01/23 23:16:42, Yoyo Zhou wrote: > prop.type_? Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:135: def _generateTypeTovalue(self, type_): On 2012/01/23 23:16:42, Yoyo Zhou wrote: > ToValue Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:232: c.append('scoped_ptr<Params> out;') On 2012/01/23 23:16:42, Yoyo Zhou wrote: > Should this be outside the for loop? > > Why not use a regular pointer for out instead of a scoped_ptr, since the caller > of Params::Create has to take ownership anyways? > > out doesn't seem to be allocated. Done. I made it a scoped_ptr so it would clean up on return NULL. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/code.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:53: On 2012/01/23 23:16:42, Yoyo Zhou wrote: > Stray newline? Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/code.py:105: 'Named arguments only. Use %%s to escape') On 2012/01/23 23:16:42, Yoyo Zhou wrote: > I still read this as use '%s' to escape, rather than use '%'s to escape. Is that > right? You could just write: use '%' to escape. Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/compiler.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:31: description='Generates a C++ model of an API from JSON schema', On 2012/01/23 23:16:42, Yoyo Zhou wrote: > nit: descriptions should end with period. Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:76: continue On 2012/01/23 23:16:42, Yoyo Zhou wrote: > This looks like it should be above the out_file = ... Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/compiler.py:101: print '%s.cc\n' % out_file On 2012/01/23 23:16:42, Yoyo Zhou wrote: > nit: extra \n Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/cpp_type_generator.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:21: self._root_namespace = root_namespace.split('::') On 2012/01/23 23:16:42, Yoyo Zhou wrote: > This always works, so you don't need the if clause. Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/cpp_type_generator.py:32: self._types[type_] = namespace On 2012/01/23 23:16:42, Yoyo Zhou wrote: > _types should have a more descriptive name, such as type_namespaces. Done. http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... File tools/json_schema_compiler/h_generator.py (right): http://codereview.chromium.org/9114036/diff/45001/tools/json_schema_compiler/... tools/json_schema_compiler/h_generator.py:114: ' serialized form of this %(classname)s object.') On 2012/01/23 22:42:07, jstritar wrote: > I think you should add a note to the comment saying it passes ownership to the > caller. Done.
LGTM http://codereview.chromium.org/9114036/diff/59001/chrome/browser/extensions/a... File chrome/browser/extensions/api/permissions/permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/59001/chrome/browser/extensions/a... chrome/browser/extensions/api/permissions/permissions_api_helpers.cc:30: scoped_ptr<Permissions> permissions(new Permissions()); I think you can use a Permissions* here and construct the scoped_ptr at the return statement without needing Pass() - see the CreateFoo example in scoped_ptr.h. http://codereview.chromium.org/9114036/diff/59001/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/59001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:285: c.Append('return %(argname)s.ToValue();') I notice this is different. Is this more correct?
http://codereview.chromium.org/9114036/diff/59001/chrome/browser/extensions/a... File chrome/browser/extensions/api/permissions/permissions_api_helpers.cc (right): http://codereview.chromium.org/9114036/diff/59001/chrome/browser/extensions/a... chrome/browser/extensions/api/permissions/permissions_api_helpers.cc:30: scoped_ptr<Permissions> permissions(new Permissions()); On 2012/01/26 00:10:38, Yoyo Zhou wrote: > I think you can use a Permissions* here and construct the scoped_ptr at the > return statement without needing Pass() - see the CreateFoo example in > scoped_ptr.h. Done. http://codereview.chromium.org/9114036/diff/59001/tools/json_schema_compiler/... File tools/json_schema_compiler/cc_generator.py (right): http://codereview.chromium.org/9114036/diff/59001/tools/json_schema_compiler/... tools/json_schema_compiler/cc_generator.py:285: c.Append('return %(argname)s.ToValue();') On 2012/01/26 00:10:38, Yoyo Zhou wrote: > I notice this is different. Is this more correct? Before it was setting a DictionaryValue which contained another DictionaryValue representing the object. Not sure why I did that...
CQ is trying da patch. Follow status at https://chromium-status.appspot.com/cq/calamity@chromium.org/9114036/66006
Presubmit check for 9114036-66006 failed and returned exit status 1. Running presubmit commit checks ... ** Presubmit Messages ** If this change has an associated bug, add BUG=[bug number]. If this change requires manual test instructions to QA team, add TEST=[instructions]. ** Presubmit Warnings ** Found lines longer than 80 characters (first 5 shown). generated_files_will_not_submit/permissions.cc, line 29, 87 chars \ generated_files_will_not_submit/permissions.cc, line 31, 95 chars \ generated_files_will_not_submit/permissions.cc, line 40, 84 chars Presubmit checks took 3.1s to calculate. Was the presubmit check useful? Please send feedback & hate mail to maruel@chromium.org!
CQ is trying da patch. Follow status at https://chromium-status.appspot.com/cq/calamity@chromium.org/9114036/67006
Try job failure for 9114036-67006 (retry) on win_rel for step "compile" (clobber build). It's a second try, previously, step "compile" failed. http://build.chromium.org/p/tryserver.chromium/buildstatus?builder=win_rel&nu...
CQ is trying da patch. Follow status at https://chromium-status.appspot.com/cq/calamity@chromium.org/9114036/70001
Change committed as 119405 |