Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 """Utilities for code generation. | |
| 5 | |
| 6 Main classes are Code for appending code and | |
| 7 TypeManager for managing types for things in model.""" | |
| 8 | |
| 9 from model import PropertyType | |
| 10 from datetime import datetime | |
| 11 | |
| 12 | |
| 13 CHROMIUM_LICENSE = ( | |
| 14 """// Copyright (c) %d The Chromium Authors. All rights reserved. | |
| 15 // Use of this source code is governed by a BSD-style license that can be | |
| 16 // found in the LICENSE file.""" % datetime.now().year | |
| 17 ) | |
| 18 WARNING_MESSAGE = """// GENERATED FROM THE API DEFINITION IN | |
| 19 // %s | |
| 20 // DO NOT EDIT.""" | |
|
not at google - send to devlin
2012/01/13 02:14:09
This is a specific to C/C++, so code.py doesn't se
calamity
2012/01/16 04:01:06
Done.
| |
| 21 | |
| 22 INDENT_SIZE = 2 | |
| 23 COMMENT_LENGTH = 80 | |
|
not at google - send to devlin
2012/01/13 02:14:09
put as members / arguments in the constructor of C
calamity
2012/01/16 04:01:06
Done.
| |
| 24 class Code(object): | |
|
not at google - send to devlin
2012/01/13 02:14:09
is explicitly extending object necessary?
calamity
2012/01/16 04:01:06
It defines it as a "new style" class. Not sure if
not at google - send to devlin
2012/01/17 01:59:24
Ah... alright. If it's like Java, classes automat
| |
| 25 """A convenience object for appending code. | |
|
not at google - send to devlin
2012/01/13 02:14:09
s/appending/constructing/
or something.
Also add
calamity
2012/01/16 04:01:06
Done.
| |
| 26 | |
| 27 Logically each object should be a block of code.""" | |
|
not at google - send to devlin
2012/01/13 02:14:09
these docstrings should have a blank line after th
calamity
2012/01/16 04:01:06
Done.
| |
| 28 def __init__(self): | |
| 29 self.code = [] | |
| 30 # TODO(calamity): Indent stack probably isn't necessary | |
|
not at google - send to devlin
2012/01/13 02:14:09
you can delete this comment and _indent_list, righ
calamity
2012/01/16 04:01:06
Done.
| |
| 31 self._indent_list = [] | |
| 32 self.indent_level = 0 | |
|
not at google - send to devlin
2012/01/13 02:14:09
these should have an _ prefix
calamity
2012/01/16 04:01:06
Done.
| |
| 33 | |
| 34 def append(self, line=''): | |
| 35 """Appends a line of code at the current indent level or just a | |
| 36 newline if line is not specified. | |
| 37 | |
| 38 This will strip trailing whitespace.""" | |
|
not at google - send to devlin
2012/01/13 02:14:09
... newline if line is not specified. Trailing whi
calamity
2012/01/16 04:01:06
Done.
| |
| 39 self.code.append(((' ' * self.indent_level) + line).rstrip()) | |
| 40 return self | |
| 41 | |
| 42 def add(self, obj): | |
|
not at google - send to devlin
2012/01/13 02:14:09
I wonder if it's more convenient to just merge thi
calamity
2012/01/16 04:01:06
Maybe. Might be unpythonic. code.Code is meant to
not at google - send to devlin
2012/01/17 01:59:24
Cool, don't worry about it then.
| |
| 43 """Concatenate another Code object onto this one. | |
| 44 | |
| 45 Appends the code at the current indent level. Will fail if there are any | |
| 46 un-interpolated format specifiers eg %s, %(something)s which helps | |
| 47 isolate any strings that haven't been substituted. | |
| 48 """ | |
| 49 if not isinstance(obj, Code): | |
| 50 raise TypeError() | |
| 51 for line in obj.code: | |
| 52 self.code.append(((' ' * self.indent_level) + line % ()).rstrip()) | |
| 53 | |
| 54 return self | |
| 55 | |
| 56 # TODO(calamity): is variable indent size necessary/a good idea? | |
|
not at google - send to devlin
2012/01/13 02:14:09
TODO unnecessary
calamity
2012/01/16 04:01:06
Done.
| |
| 57 def sblock(self, line): | |
| 58 """Starts a code block. | |
|
not at google - send to devlin
2012/01/13 02:14:09
"""Starts a code block, by appending a line of cod
calamity
2012/01/16 04:01:06
Done.
| |
| 59 | |
| 60 Adds a line of code and then increases the indent level.""" | |
| 61 self.append(line) | |
| 62 self.indent_level += INDENT_SIZE | |
| 63 return self | |
| 64 | |
| 65 def eblock(self, line=''): | |
| 66 """Ends a code block. | |
|
not at google - send to devlin
2012/01/13 02:14:09
"""Ends a code block, by decreasing the indent lev
calamity
2012/01/16 04:01:06
Done.
| |
| 67 | |
| 68 Decreases the indent level and then adds the line of code. | |
| 69 """ | |
| 70 # TODO(calamity): Decide if type checking is necessary | |
| 71 #if not isinstance(line, basestring): | |
| 72 # raise TypeError | |
| 73 self.indent_level -= INDENT_SIZE | |
| 74 self.append(line) | |
| 75 return self | |
| 76 | |
| 77 def comment(self, comment): | |
| 78 """Adds the given string as a comment. | |
| 79 | |
| 80 Will split the comment if it's too long. Use mainly for variable length | |
| 81 comments. Otherwise just use code.append('// ...') for comments. | |
| 82 """ | |
| 83 comment_symbol = '// ' | |
| 84 max_len = COMMENT_LENGTH - self.indent_level - len(comment_symbol) | |
| 85 while len(comment) >= max_len: | |
| 86 line = comment[0:max_len] | |
| 87 last_space = line.rfind(' ') | |
| 88 if last_space != -1: | |
| 89 line = line[0:last_space] | |
| 90 comment = comment[last_space + 1:] | |
| 91 else: | |
| 92 comment = comment[max_len:] | |
| 93 self.append(comment_symbol + line) | |
| 94 self.append(comment_symbol + comment) | |
| 95 return self | |
| 96 | |
| 97 def substitute(self, d): | |
| 98 """Goes through each line and interpolates using the given dict. | |
| 99 | |
| 100 Raises type error if passed something that isn't a dict.""" | |
|
not at google - send to devlin
2012/01/13 02:14:09
"Raises type error" comment is unnecessary.
calamity
2012/01/16 04:01:06
The style guide says it should list exceptions it
not at google - send to devlin
2012/01/17 01:59:24
This isn't really an exception though, it's a prog
calamity
2012/01/18 05:43:08
Done.
| |
| 101 if not isinstance(d, dict): | |
| 102 raise TypeError('Passed argument is not a dictionary: ' + d) | |
| 103 for i, line in enumerate(self.code): | |
| 104 # Only need to check %s because arg is a dict and python will allow | |
| 105 # '%s %(named)s' but just about nothing else | |
| 106 if '%s' in self.code[i] or '%r' in self.code[i]: | |
| 107 raise TypeError('%s or %r found in substitution.' | |
| 108 'Named arguments only. Use %%s to escape') | |
| 109 self.code[i] = line % d | |
| 110 return self | |
| 111 | |
| 112 def render(self): | |
| 113 """Returns the code joined together as a string.""" | |
|
not at google - send to devlin
2012/01/13 02:14:09
"""Renders the Code as a string.
"""
calamity
2012/01/16 04:01:06
Done.
| |
| 114 return '\n'.join(self.code) | |
| 115 | |
| 116 def cpp_name(s): | |
|
not at google - send to devlin
2012/01/13 02:14:09
this also belongs in a c++ util class
calamity
2012/01/16 04:01:06
Done.
| |
| 117 """Translates a namespace name or function name into something more | |
| 118 suited to C++. | |
| 119 | |
| 120 eg experimental.downloads -> Experimental_Downloads | |
| 121 updateAll -> UpdateAll. | |
| 122 """ | |
| 123 return '_'.join([x[0].upper() + x[1:] for x in s.split('.')]) | |
| 124 | |
| OLD | NEW |