File size: 2,001 Bytes
c65f48d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
from collections import defaultdict
class DuplicatedNameError(NameError):
pass
class NameScope(object):
def __init__(self):
self._useset = set([''])
self._basenamemap = defaultdict(int)
def is_used(self, name):
return name in self._useset
def register(self, name, deduplicate=False):
if deduplicate:
name = self.deduplicate(name)
elif self.is_used(name):
raise DuplicatedNameError(name)
self._useset.add(name)
return name
def deduplicate(self, name):
basename = name
while self.is_used(name):
ident = self._basenamemap[basename] + 1
self._basenamemap[basename] = ident
name = "{0}.{1}".format(basename, ident)
return name
def get_child(self):
return type(self)(parent=self)
class _StrCaching(object):
def _clear_string_cache(self):
try:
del self.__cached_str
except AttributeError:
pass
def __str__(self):
try:
return self.__cached_str
except AttributeError:
s = self.__cached_str = self._to_string()
return s
class _StringReferenceCaching(object):
def get_reference(self):
try:
return self.__cached_refstr
except AttributeError:
s = self.__cached_refstr = self._get_reference()
return s
class _HasMetadata(object):
def set_metadata(self, name, node):
"""
Attach unnamed metadata *node* to the metadata slot *name* of this
value.
"""
self.metadata[name] = node
def _stringify_metadata(self, leading_comma=False):
if self.metadata:
buf = []
if leading_comma:
buf.append("")
buf += ["!{0} {1}".format(k, v.get_reference())
for k, v in self.metadata.items()]
return ', '.join(buf)
else:
return ''
|