mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-09 23:34:45 +08:00
parser decorators
This commit is contained in:
@@ -249,6 +249,10 @@ for s in cmpl.parser.top.subscopes[2].subscopes:
|
|||||||
names = s.get_set_vars()
|
names = s.get_set_vars()
|
||||||
handle_names(names)
|
handle_names(names)
|
||||||
|
|
||||||
|
print
|
||||||
|
print 'start/end'
|
||||||
|
for s in cmpl.parser.top.subscopes:
|
||||||
|
print repr(s)
|
||||||
|
|
||||||
p = cmpl.parser
|
p = cmpl.parser
|
||||||
s = p.top
|
s = p.top
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ Ignored statements:
|
|||||||
|
|
||||||
TODO take special care for future imports
|
TODO take special care for future imports
|
||||||
TODO check meta classes
|
TODO check meta classes
|
||||||
|
TODO evaluate options to either replace tokenize or change its behavior for
|
||||||
|
multiline parentheses (if they don't close, there must be a break somewhere)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import tokenize
|
import tokenize
|
||||||
@@ -71,10 +73,12 @@ class Scope(object):
|
|||||||
self.parent = None
|
self.parent = None
|
||||||
self.indent = indent
|
self.indent = indent
|
||||||
self.line_nr = line_nr
|
self.line_nr = line_nr
|
||||||
|
self.line_end = None
|
||||||
|
|
||||||
def add_scope(self, sub):
|
def add_scope(self, sub, decorators):
|
||||||
# print 'push scope: [%s@%s]' % (sub.line_nr, sub.indent)
|
# print 'push scope: [%s@%s]' % (sub.line_nr, sub.indent)
|
||||||
sub.parent = self
|
sub.parent = self
|
||||||
|
sub.decorators = decorators
|
||||||
self.subscopes.append(sub)
|
self.subscopes.append(sub)
|
||||||
return sub
|
return sub
|
||||||
|
|
||||||
@@ -181,6 +185,15 @@ class Scope(object):
|
|||||||
"""
|
"""
|
||||||
return not (self.imports or self.subscopes or self.statements)
|
return not (self.imports or self.subscopes or self.statements)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
try:
|
||||||
|
name = self.name
|
||||||
|
except:
|
||||||
|
name = self.command
|
||||||
|
|
||||||
|
return "<%s: %s@%s-%s>" % \
|
||||||
|
(self.__class__.__name__, name, self.line_nr, self.line_end)
|
||||||
|
|
||||||
|
|
||||||
class Class(Scope):
|
class Class(Scope):
|
||||||
"""
|
"""
|
||||||
@@ -201,12 +214,11 @@ class Class(Scope):
|
|||||||
super(Class, self).__init__(indent, line_nr, docstr)
|
super(Class, self).__init__(indent, line_nr, docstr)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.supers = supers
|
self.supers = supers
|
||||||
|
self.decorators = []
|
||||||
def __repr__(self):
|
|
||||||
return "<Class instance: %s@%s>" % (self.name, self.line_nr)
|
|
||||||
|
|
||||||
def get_code(self, first_indent=False, indention=" "):
|
def get_code(self, first_indent=False, indention=" "):
|
||||||
str = 'class %s' % (self.name)
|
str = "\n".join('@' + stmt.get_code() for stmt in self.decorators)
|
||||||
|
str += 'class %s' % (self.name)
|
||||||
if len(self.supers) > 0:
|
if len(self.supers) > 0:
|
||||||
sup = ','.join(stmt.code for stmt in self.supers)
|
sup = ','.join(stmt.code for stmt in self.supers)
|
||||||
str += '(%s)' % sup
|
str += '(%s)' % sup
|
||||||
@@ -254,13 +266,12 @@ class Function(Scope):
|
|||||||
Scope.__init__(self, indent, line_nr, docstr)
|
Scope.__init__(self, indent, line_nr, docstr)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.params = params
|
self.params = params
|
||||||
|
self.decorators = []
|
||||||
def __repr__(self):
|
|
||||||
return "<Function instance: %s@%s>" % (self.name, self.line_nr)
|
|
||||||
|
|
||||||
def get_code(self, first_indent=False, indention=" "):
|
def get_code(self, first_indent=False, indention=" "):
|
||||||
|
str = "\n".join('@' + stmt.get_code() for stmt in self.decorators)
|
||||||
params = ','.join([stmt.code for stmt in self.params])
|
params = ','.join([stmt.code for stmt in self.params])
|
||||||
str = "def %s(%s):\n" % (self.name, params)
|
str += "def %s(%s):\n" % (self.name, params)
|
||||||
str += super(Function, self).get_code(True, indention)
|
str += super(Function, self).get_code(True, indention)
|
||||||
if self.is_empty():
|
if self.is_empty():
|
||||||
str += "pass\n"
|
str += "pass\n"
|
||||||
@@ -300,7 +311,6 @@ class Flow(Scope):
|
|||||||
:type set_vars: list
|
:type set_vars: list
|
||||||
"""
|
"""
|
||||||
def __init__(self, command, statement, indent, line_nr, set_vars=None):
|
def __init__(self, command, statement, indent, line_nr, set_vars=None):
|
||||||
name = "%s@%s" % (command, line_nr)
|
|
||||||
super(Flow, self).__init__(indent, line_nr, '')
|
super(Flow, self).__init__(indent, line_nr, '')
|
||||||
self.command = command
|
self.command = command
|
||||||
self.statement = statement
|
self.statement = statement
|
||||||
@@ -310,9 +320,6 @@ class Flow(Scope):
|
|||||||
self.set_vars = set_vars
|
self.set_vars = set_vars
|
||||||
self.next = None
|
self.next = None
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<Flow instance: %s@%s>" % (self.command, self.line_nr)
|
|
||||||
|
|
||||||
def get_code(self, first_indent=False, indention=" "):
|
def get_code(self, first_indent=False, indention=" "):
|
||||||
if self.set_vars:
|
if self.set_vars:
|
||||||
vars = ",".join(map(lambda x: x.get_code(), self.set_vars))
|
vars = ",".join(map(lambda x: x.get_code(), self.set_vars))
|
||||||
@@ -785,12 +792,13 @@ class PyFuzzyParser(object):
|
|||||||
self.gen = tokenize.generate_tokens(buf.readline)
|
self.gen = tokenize.generate_tokens(buf.readline)
|
||||||
self.currentscope = self.scope
|
self.currentscope = self.scope
|
||||||
|
|
||||||
try:
|
|
||||||
extended_flow = ['else', 'except', 'finally']
|
extended_flow = ['else', 'except', 'finally']
|
||||||
statement_toks = ['{', '[', '(', '`']
|
statement_toks = ['{', '[', '(', '`']
|
||||||
|
|
||||||
|
decorators = []
|
||||||
freshscope = True
|
freshscope = True
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
token_type, tok, indent = self.next()
|
token_type, tok, indent = self.next()
|
||||||
dbg('main: tok=[%s] type=[%s] indent=[%s]'\
|
dbg('main: tok=[%s] type=[%s] indent=[%s]'\
|
||||||
% (tok, token_type, indent))
|
% (tok, token_type, indent))
|
||||||
@@ -799,16 +807,18 @@ class PyFuzzyParser(object):
|
|||||||
print 'dedent', self.scope
|
print 'dedent', self.scope
|
||||||
token_type, tok, indent = self.next()
|
token_type, tok, indent = self.next()
|
||||||
if indent <= self.scope.indent:
|
if indent <= self.scope.indent:
|
||||||
|
self.scope.line_end = self.line_nr
|
||||||
self.scope = self.scope.parent
|
self.scope = self.scope.parent
|
||||||
|
|
||||||
# check again for unindented stuff. this is true for syntax
|
# check again for unindented stuff. this is true for syntax
|
||||||
# errors. only check for names, because thats relevant here. If
|
# errors. only check for names, because thats relevant here. If
|
||||||
# some docstrings are not indented, I don't care.
|
# some docstrings are not indented, I don't care.
|
||||||
if indent <= self.scope.indent \
|
while indent <= self.scope.indent \
|
||||||
and token_type in [tokenize.NAME] \
|
and token_type in [tokenize.NAME] \
|
||||||
and self.scope != self.top:
|
and self.scope != self.top:
|
||||||
print 'syntax_err, dedent @%s - %s<=%s', \
|
print 'syntax_err, dedent @%s - %s<=%s', \
|
||||||
(self.line_nr, indent, self.scope.indent)
|
(self.line_nr, indent, self.scope.indent)
|
||||||
|
self.scope.line_end = self.line_nr
|
||||||
self.scope = self.scope.parent
|
self.scope = self.scope.parent
|
||||||
|
|
||||||
if tok == 'def':
|
if tok == 'def':
|
||||||
@@ -818,14 +828,16 @@ class PyFuzzyParser(object):
|
|||||||
continue
|
continue
|
||||||
dbg("new scope: function %s" % (func.name))
|
dbg("new scope: function %s" % (func.name))
|
||||||
freshscope = True
|
freshscope = True
|
||||||
self.scope = self.scope.add_scope(func)
|
self.scope = self.scope.add_scope(func, decorators)
|
||||||
|
decorators = []
|
||||||
elif tok == 'class':
|
elif tok == 'class':
|
||||||
cls = self._parseclass(indent)
|
cls = self._parseclass(indent)
|
||||||
if cls is None:
|
if cls is None:
|
||||||
continue
|
continue
|
||||||
freshscope = True
|
freshscope = True
|
||||||
dbg("new scope: class %s" % (cls.name))
|
dbg("new scope: class %s" % (cls.name))
|
||||||
self.scope = self.scope.add_scope(cls)
|
self.scope = self.scope.add_scope(cls, decorators)
|
||||||
|
decorators = []
|
||||||
# import stuff
|
# import stuff
|
||||||
elif tok == 'import':
|
elif tok == 'import':
|
||||||
imports = self._parseimportlist()
|
imports = self._parseimportlist()
|
||||||
@@ -891,6 +903,10 @@ class PyFuzzyParser(object):
|
|||||||
# add the global to the top, because there it is
|
# add the global to the top, because there it is
|
||||||
# important.
|
# important.
|
||||||
self.top.add_global(name)
|
self.top.add_global(name)
|
||||||
|
# decorator
|
||||||
|
elif tok == '@':
|
||||||
|
stmt, tok = self._parse_statement()
|
||||||
|
decorators.append(stmt)
|
||||||
elif tok == 'pass':
|
elif tok == 'pass':
|
||||||
continue
|
continue
|
||||||
# check for docstrings
|
# check for docstrings
|
||||||
@@ -908,7 +924,7 @@ class PyFuzzyParser(object):
|
|||||||
#else:
|
#else:
|
||||||
#print "_not_implemented_", tok, self.parserline
|
#print "_not_implemented_", tok, self.parserline
|
||||||
except StopIteration: # thrown on EOF
|
except StopIteration: # thrown on EOF
|
||||||
pass
|
break
|
||||||
#except StopIteration:
|
#except StopIteration:
|
||||||
# dbg("parse error: %s, %s @ %s" %
|
# dbg("parse error: %s, %s @ %s" %
|
||||||
# (sys.exc_info()[0], sys.exc_info()[1], self.parserline))
|
# (sys.exc_info()[0], sys.exc_info()[1], self.parserline))
|
||||||
|
|||||||
4
test.py
4
test.py
@@ -56,11 +56,12 @@ c = a or c
|
|||||||
|
|
||||||
class Empty():
|
class Empty():
|
||||||
pass
|
pass
|
||||||
#def blub():
|
def blub():
|
||||||
|
|
||||||
cdef = 5
|
cdef = 5
|
||||||
cdef cdef
|
cdef cdef
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
|
if 1:if 2:for a in range(3): exec a
|
||||||
asdf = aaa
|
asdf = aaa
|
||||||
print 'blub'
|
print 'blub'
|
||||||
else:
|
else:
|
||||||
@@ -81,6 +82,7 @@ def ass_test(a):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
matrix = [[1,2,3], [4,5,6], [7,8,9]]
|
matrix = [[1,2,3], [4,5,6], [7,8,9]]
|
||||||
|
@property
|
||||||
def flow_test(a):
|
def flow_test(a):
|
||||||
global matrix
|
global matrix
|
||||||
for i in matrix:
|
for i in matrix:
|
||||||
|
|||||||
Reference in New Issue
Block a user