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

Side by Side Diff: tools/json_schema_compiler/code.py

Issue 9491002: json_schema_compiler: any, additionalProperties, functions on types (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: add any in arrays to util.h Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/json_schema_compiler/cc_generator.py ('k') | tools/json_schema_compiler/code_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 class Code(object): 5 class Code(object):
6 """A convenience object for constructing code. 6 """A convenience object for constructing code.
7 7
8 Logically each object should be a block of code. All methods except |Render| 8 Logically each object should be a block of code. All methods except |Render|
9 and |IsEmpty| return self. 9 and |IsEmpty| return self.
10 """ 10 """
11 def __init__(self, indent_size=2, comment_length=80): 11 def __init__(self, indent_size=2, comment_length=80):
12 self._code = [] 12 self._code = []
13 self._indent_level = 0 13 self._indent_level = 0
14 self._indent_size = indent_size 14 self._indent_size = indent_size
15 self._comment_length = comment_length 15 self._comment_length = comment_length
16 16
17 def Append(self, line=''): 17 def Append(self, line='', substitute=True):
18 """Appends a line of code at the current indent level or just a newline if 18 """Appends a line of code at the current indent level or just a newline if
19 line is not specified. Trailing whitespace is stripped. 19 line is not specified. Trailing whitespace is stripped.
20
21 substitute: indicated whether this line should be affected by
22 code.Substitute().
20 """ 23 """
21 self._code.append(((' ' * self._indent_level) + line).rstrip()) 24 self._code.append(Line(((' ' * self._indent_level) + line).rstrip(),
25 substitute=substitute))
22 return self 26 return self
23 27
24 def IsEmpty(self): 28 def IsEmpty(self):
25 """Returns True if the Code object is empty. 29 """Returns True if the Code object is empty.
26 """ 30 """
27 return not bool(self._code) 31 return not bool(self._code)
28 32
29 def Concat(self, obj): 33 def Concat(self, obj):
30 """Concatenate another Code object onto this one. Trailing whitespace is 34 """Concatenate another Code object onto this one. Trailing whitespace is
31 stripped. 35 stripped.
32 36
33 Appends the code at the current indent level. Will fail if there are any 37 Appends the code at the current indent level. Will fail if there are any
34 un-interpolated format specifiers eg %s, %(something)s which helps 38 un-interpolated format specifiers eg %s, %(something)s which helps
35 isolate any strings that haven't been substituted. 39 isolate any strings that haven't been substituted.
36 """ 40 """
37 if not isinstance(obj, Code): 41 if not isinstance(obj, Code):
38 raise TypeError(type(obj)) 42 raise TypeError(type(obj))
39 assert self is not obj 43 assert self is not obj
40 for line in obj._code: 44 for line in obj._code:
41 try: 45 try:
42 # line % () will fail if any substitution tokens are left in line 46 # line % () will fail if any substitution tokens are left in line
43 self._code.append(((' ' * self._indent_level) + line % ()).rstrip()) 47 if line.substitute:
48 line.value %= ()
44 except TypeError: 49 except TypeError:
45 raise TypeError('Unsubstituted value when concatting\n' + line) 50 raise TypeError('Unsubstituted value when concatting\n' + line)
51 except ValueError:
52 raise ValueError('Stray % character when concatting\n' + line)
53 self.Append(line.value, line.substitute)
46 54
47 return self 55 return self
48 56
49 def Sblock(self, line=''): 57 def Sblock(self, line=''):
50 """Starts a code block. 58 """Starts a code block.
51 59
52 Appends a line of code and then increases the indent level. 60 Appends a line of code and then increases the indent level.
53 """ 61 """
54 self.Append(line) 62 self.Append(line)
55 self._indent_level += self._indent_size 63 self._indent_level += self._indent_size
56 return self 64 return self
57 65
58 def Eblock(self, line=''): 66 def Eblock(self, line=''):
59 """Ends a code block by decreasing and then appending a line (or a blank 67 """Ends a code block by decreasing and then appending a line (or a blank
60 line if not given). 68 line if not given).
61 """ 69 """
62 # TODO(calamity): Decide if type checking is necessary 70 # TODO(calamity): Decide if type checking is necessary
63 #if not isinstance(line, basestring): 71 #if not isinstance(line, basestring):
64 # raise TypeError 72 # raise TypeError
65 self._indent_level -= self._indent_size 73 self._indent_level -= self._indent_size
66 self.Append(line) 74 self.Append(line)
67 return self 75 return self
68 76
69 # TODO(calamity): Make comment its own class or something and Render at 77 def Comment(self, comment, comment_prefix='// '):
70 # self.Render() time
71 def Comment(self, comment):
72 """Adds the given string as a comment. 78 """Adds the given string as a comment.
73 79
74 Will split the comment if it's too long. Use mainly for variable length 80 Will split the comment if it's too long. Use mainly for variable length
75 comments. Otherwise just use code.Append('// ...') for comments. 81 comments. Otherwise just use code.Append('// ...') for comments.
82
83 Unaffected by code.Substitute().
76 """ 84 """
77 comment_symbol = '// ' 85 max_len = self._comment_length - self._indent_level - len(comment_prefix)
78 max_len = self._comment_length - self._indent_level - len(comment_symbol)
79 while len(comment) >= max_len: 86 while len(comment) >= max_len:
80 line = comment[0:max_len] 87 line = comment[0:max_len]
81 last_space = line.rfind(' ') 88 last_space = line.rfind(' ')
82 if last_space != -1: 89 if last_space != -1:
83 line = line[0:last_space] 90 line = line[0:last_space]
84 comment = comment[last_space + 1:] 91 comment = comment[last_space + 1:]
85 else: 92 else:
86 comment = comment[max_len:] 93 comment = comment[max_len:]
87 self.Append(comment_symbol + line) 94 self.Append(comment_prefix + line, substitute=False)
88 self.Append(comment_symbol + comment) 95 self.Append(comment_prefix + comment, substitute=False)
89 return self 96 return self
90 97
91 def Substitute(self, d): 98 def Substitute(self, d):
92 """Goes through each line and interpolates using the given dict. 99 """Goes through each line and interpolates using the given dict.
93 100
94 Raises type error if passed something that isn't a dict 101 Raises type error if passed something that isn't a dict
95 102
96 Use for long pieces of code using interpolation with the same variables 103 Use for long pieces of code using interpolation with the same variables
97 repeatedly. This will reduce code and allow for named placeholders which 104 repeatedly. This will reduce code and allow for named placeholders which
98 are more clear. 105 are more clear.
99 """ 106 """
100 if not isinstance(d, dict): 107 if not isinstance(d, dict):
101 raise TypeError('Passed argument is not a dictionary: ' + d) 108 raise TypeError('Passed argument is not a dictionary: ' + d)
102 for i, line in enumerate(self._code): 109 for i, line in enumerate(self._code):
103 # Only need to check %s because arg is a dict and python will allow 110 if self._code[i].substitute:
104 # '%s %(named)s' but just about nothing else 111 # Only need to check %s because arg is a dict and python will allow
105 if '%s' in self._code[i] or '%r' in self._code[i]: 112 # '%s %(named)s' but just about nothing else
106 raise TypeError('"%s" or "%r" found in substitution. ' 113 if '%s' in self._code[i].value or '%r' in self._code[i].value:
107 'Named arguments only. Use "%" to escape') 114 raise TypeError('"%s" or "%r" found in substitution. '
108 self._code[i] = line % d 115 'Named arguments only. Use "%" to escape')
116 self._code[i].value = line.value % d
117 self._code[i].substitute = False
109 return self 118 return self
110 119
111 def Render(self): 120 def Render(self):
112 """Renders Code as a string. 121 """Renders Code as a string.
113 """ 122 """
114 return '\n'.join(self._code) 123 return '\n'.join([l.value for l in self._code])
115 124
125 class Line(object):
126 """A line of code.
127 """
128 def __init__(self, value, substitute=True):
129 self.value = value
130 self.substitute = substitute
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/cc_generator.py ('k') | tools/json_schema_compiler/code_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698