blob: 757c57fb041f87a6e01a8fafa358aee598c22316 [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import itertools
import symbol
import token
from py_utils.refactor.annotated_symbol import base_symbol
from py_utils.refactor import snippet
__all__ = [
'Reference',
]
class Reference(base_symbol.AnnotatedSymbol):
@classmethod
def Annotate(cls, nodes):
if not nodes:
return None
if nodes[0].type != symbol.atom:
return None
if not nodes[0].children or nodes[0].children[0].type != token.NAME:
return None
for i in xrange(1, len(nodes)):
if not nodes:
break
if nodes[i].type != symbol.trailer:
break
if len(nodes[i].children) != 2:
break
if (nodes[i].children[0].type != token.DOT or
nodes[i].children[1].type != token.NAME):
break
else:
i = len(nodes)
return [cls(nodes[:i])] + nodes[i:]
def __init__(self, children):
super(Reference, self).__init__(-1, children)
@property
def type_name(self):
return 'attribute_reference'
@property
def value(self):
return ''.join(token_snippet.value
for child in self.children
for token_snippet in child.children)
@value.setter
def value(self, value):
value_parts = value.split('.')
# If we have too many children, cut the list down to size.
self._children = self._children[:len(value_parts)]
# Update child nodes.
for child, value_part in itertools.izip_longest(
self._children, value_parts):
if child:
# Modify existing children. This helps preserve comments and spaces.
child.children[-1].value = value_part
else:
# Add children as needed.
token_snippets = [
snippet.TokenSnippet.Create(token.DOT, '.'),
snippet.TokenSnippet.Create(token.NAME, value_part),
]
self._children.append(snippet.Symbol(symbol.trailer, token_snippets))