| Index: tools/json_schema_compiler/code.py
|
| diff --git a/tools/json_schema_compiler/code.py b/tools/json_schema_compiler/code.py
|
| index c19029a1ef0a2b3ba5135cbfc57dd9b12b0d08cb..07f657474472ea53fc459eae33df5bcff21cc85b 100644
|
| --- a/tools/json_schema_compiler/code.py
|
| +++ b/tools/json_schema_compiler/code.py
|
| @@ -14,11 +14,15 @@ class Code(object):
|
| self._indent_size = indent_size
|
| self._comment_length = comment_length
|
|
|
| - def Append(self, line=''):
|
| + def Append(self, line='', substitute=True):
|
| """Appends a line of code at the current indent level or just a newline if
|
| line is not specified. Trailing whitespace is stripped.
|
| +
|
| + substitute: indicated whether this line should be affected by
|
| + code.Substitute().
|
| """
|
| - self._code.append(((' ' * self._indent_level) + line).rstrip())
|
| + self._code.append(Line(((' ' * self._indent_level) + line).rstrip(),
|
| + substitute=substitute))
|
| return self
|
|
|
| def IsEmpty(self):
|
| @@ -40,9 +44,13 @@ class Code(object):
|
| for line in obj._code:
|
| try:
|
| # line % () will fail if any substitution tokens are left in line
|
| - self._code.append(((' ' * self._indent_level) + line % ()).rstrip())
|
| + if line.substitute:
|
| + line.value %= ()
|
| except TypeError:
|
| raise TypeError('Unsubstituted value when concatting\n' + line)
|
| + except ValueError:
|
| + raise ValueError('Stray % character when concatting\n' + line)
|
| + self.Append(line.value, line.substitute)
|
|
|
| return self
|
|
|
| @@ -66,16 +74,15 @@ class Code(object):
|
| self.Append(line)
|
| return self
|
|
|
| - # TODO(calamity): Make comment its own class or something and Render at
|
| - # self.Render() time
|
| - def Comment(self, comment):
|
| + def Comment(self, comment, comment_prefix='// '):
|
| """Adds the given string as a comment.
|
|
|
| Will split the comment if it's too long. Use mainly for variable length
|
| comments. Otherwise just use code.Append('// ...') for comments.
|
| +
|
| + Unaffected by code.Substitute().
|
| """
|
| - comment_symbol = '// '
|
| - max_len = self._comment_length - self._indent_level - len(comment_symbol)
|
| + max_len = self._comment_length - self._indent_level - len(comment_prefix)
|
| while len(comment) >= max_len:
|
| line = comment[0:max_len]
|
| last_space = line.rfind(' ')
|
| @@ -84,8 +91,8 @@ class Code(object):
|
| comment = comment[last_space + 1:]
|
| else:
|
| comment = comment[max_len:]
|
| - self.Append(comment_symbol + line)
|
| - self.Append(comment_symbol + comment)
|
| + self.Append(comment_prefix + line, substitute=False)
|
| + self.Append(comment_prefix + comment, substitute=False)
|
| return self
|
|
|
| def Substitute(self, d):
|
| @@ -100,16 +107,24 @@ class Code(object):
|
| if not isinstance(d, dict):
|
| raise TypeError('Passed argument is not a dictionary: ' + d)
|
| for i, line in enumerate(self._code):
|
| - # Only need to check %s because arg is a dict and python will allow
|
| - # '%s %(named)s' but just about nothing else
|
| - if '%s' in self._code[i] or '%r' in self._code[i]:
|
| - raise TypeError('"%s" or "%r" found in substitution. '
|
| - 'Named arguments only. Use "%" to escape')
|
| - self._code[i] = line % d
|
| + if self._code[i].substitute:
|
| + # Only need to check %s because arg is a dict and python will allow
|
| + # '%s %(named)s' but just about nothing else
|
| + if '%s' in self._code[i].value or '%r' in self._code[i].value:
|
| + raise TypeError('"%s" or "%r" found in substitution. '
|
| + 'Named arguments only. Use "%" to escape')
|
| + self._code[i].value = line.value % d
|
| + self._code[i].substitute = False
|
| return self
|
|
|
| def Render(self):
|
| """Renders Code as a string.
|
| """
|
| - return '\n'.join(self._code)
|
| + return '\n'.join([l.value for l in self._code])
|
|
|
| +class Line(object):
|
| + """A line of code.
|
| + """
|
| + def __init__(self, value, substitute=True):
|
| + self.value = value
|
| + self.substitute = substitute
|
|
|