summaryrefslogtreecommitdiff
path: root/scoped_nodes.py
diff options
context:
space:
mode:
authorEevee (Alex Munroe) <amunroe@yelp.com>2014-03-24 18:00:17 -0700
committerEevee (Alex Munroe) <amunroe@yelp.com>2014-07-01 17:33:00 -0700
commit53013fa01f45114c1b8ee87527eab4fbeef8a113 (patch)
treed4ea5d9e01a4e746ea48037443a62bdb40d250da /scoped_nodes.py
parent2e13d989dbf9a097c679e4e1ca71e59fc9e5524f (diff)
downloadastroid-git-53013fa01f45114c1b8ee87527eab4fbeef8a113.tar.gz
Speed up rebuilder considerably by computing line numbers lazily.
Fetching the last child of each of hundreds of thousands of nodes is relatively expensive, and most of the time this information is never used, so don't actually figure it out until it's asked for. Saves the overhead of quite a few function calls, too.
Diffstat (limited to 'scoped_nodes.py')
-rw-r--r--scoped_nodes.py32
1 files changed, 18 insertions, 14 deletions
diff --git a/scoped_nodes.py b/scoped_nodes.py
index 389ebe71..f5d1c428 100644
--- a/scoped_nodes.py
+++ b/scoped_nodes.py
@@ -580,16 +580,20 @@ class Function(Statement, Lambda):
self.extra_decorators = []
self.instance_attrs = {}
- def set_line_info(self, lastchild):
- self.fromlineno = self.lineno
- # lineno is the line number of the first decorator, we want the def statement lineno
+ @cachedproperty
+ def fromlineno(self):
+ # lineno is the line number of the first decorator, we want the def
+ # statement lineno
+ lineno = self.lineno
if self.decorators is not None:
- self.fromlineno += sum(node.tolineno - node.lineno + 1
+ lineno += sum(node.tolineno - node.lineno + 1
for node in self.decorators.nodes)
- if self.args.fromlineno < self.fromlineno:
- self.args.fromlineno = self.fromlineno
- self.tolineno = lastchild.tolineno
- self.blockstart_tolineno = self.args.tolineno
+
+ return lineno
+
+ @cachedproperty
+ def blockstart_tolineno(self):
+ return self.args.tolineno
def block_range(self, lineno):
"""return block line numbers.
@@ -819,12 +823,12 @@ class Class(Statement, LocalsDictNodeNG, FilterStmtsMixin):
doc="boolean indicating if it's a new style class"
"or not")
- def set_line_info(self, lastchild):
- self.fromlineno = self.lineno
- self.blockstart_tolineno = self.bases and self.bases[-1].tolineno or self.fromlineno
- if lastchild is not None:
- self.tolineno = lastchild.tolineno
- # else this is a class with only a docstring, then tolineno is (should be) already ok
+ @cachedproperty
+ def blockstart_tolineno(self):
+ if self.bases:
+ return self.bases[-1].tolineno
+ else:
+ return self.fromlineno
def block_range(self, lineno):
"""return block line numbers.