Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Unified Diff: tools/telemetry/third_party/rope/rope/refactor/functionutils.py

Issue 1132103009: Example of refactoring using rope library. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/third_party/rope/rope/refactor/functionutils.py
diff --git a/tools/telemetry/third_party/rope/rope/refactor/functionutils.py b/tools/telemetry/third_party/rope/rope/refactor/functionutils.py
new file mode 100644
index 0000000000000000000000000000000000000000..58baf9174fd9bec2f18849063f832847103cfdea
--- /dev/null
+++ b/tools/telemetry/third_party/rope/rope/refactor/functionutils.py
@@ -0,0 +1,222 @@
+import rope.base.exceptions
+import rope.base.pyobjects
+from rope.base.builtins import Lambda
+from rope.base import worder
+
+
+class DefinitionInfo(object):
+
+ def __init__(self, function_name, is_method, args_with_defaults,
+ args_arg, keywords_arg):
+ self.function_name = function_name
+ self.is_method = is_method
+ self.args_with_defaults = args_with_defaults
+ self.args_arg = args_arg
+ self.keywords_arg = keywords_arg
+
+ def to_string(self):
+ return '%s(%s)' % (self.function_name, self.arguments_to_string())
+
+ def arguments_to_string(self, from_index=0):
+ params = []
+ for arg, default in self.args_with_defaults:
+ if default is not None:
+ params.append('%s=%s' % (arg, default))
+ else:
+ params.append(arg)
+ if self.args_arg is not None:
+ params.append('*' + self.args_arg)
+ if self.keywords_arg:
+ params.append('**' + self.keywords_arg)
+ return ', '.join(params[from_index:])
+
+ @staticmethod
+ def _read(pyfunction, code):
+ kind = pyfunction.get_kind()
+ is_method = kind == 'method'
+ is_lambda = kind == 'lambda'
+ info = _FunctionParser(code, is_method, is_lambda)
+ args, keywords = info.get_parameters()
+ args_arg = None
+ keywords_arg = None
+ if args and args[-1].startswith('**'):
+ keywords_arg = args[-1][2:]
+ del args[-1]
+ if args and args[-1].startswith('*'):
+ args_arg = args[-1][1:]
+ del args[-1]
+ args_with_defaults = [(name, None) for name in args]
+ args_with_defaults.extend(keywords)
+ return DefinitionInfo(info.get_function_name(), is_method,
+ args_with_defaults, args_arg, keywords_arg)
+
+ @staticmethod
+ def read(pyfunction):
+ pymodule = pyfunction.get_module()
+ word_finder = worder.Worder(pymodule.source_code)
+ lineno = pyfunction.get_ast().lineno
+ start = pymodule.lines.get_line_start(lineno)
+ if isinstance(pyfunction, Lambda):
+ call = word_finder.get_lambda_and_args(start)
+ else:
+ call = word_finder.get_function_and_args_in_header(start)
+ return DefinitionInfo._read(pyfunction, call)
+
+
+class CallInfo(object):
+
+ def __init__(self, function_name, args, keywords, args_arg,
+ keywords_arg, implicit_arg, constructor):
+ self.function_name = function_name
+ self.args = args
+ self.keywords = keywords
+ self.args_arg = args_arg
+ self.keywords_arg = keywords_arg
+ self.implicit_arg = implicit_arg
+ self.constructor = constructor
+
+ def to_string(self):
+ function = self.function_name
+ if self.implicit_arg:
+ function = self.args[0] + '.' + self.function_name
+ params = []
+ start = 0
+ if self.implicit_arg or self.constructor:
+ start = 1
+ if self.args[start:]:
+ params.extend(self.args[start:])
+ if self.keywords:
+ params.extend(['%s=%s' % (name, value)
+ for name, value in self.keywords])
+ if self.args_arg is not None:
+ params.append('*' + self.args_arg)
+ if self.keywords_arg:
+ params.append('**' + self.keywords_arg)
+ return '%s(%s)' % (function, ', '.join(params))
+
+ @staticmethod
+ def read(primary, pyname, definition_info, code):
+ is_method_call = CallInfo._is_method_call(primary, pyname)
+ is_constructor = CallInfo._is_class(pyname)
+ is_classmethod = CallInfo._is_classmethod(pyname)
+ info = _FunctionParser(code, is_method_call or is_classmethod)
+ args, keywords = info.get_parameters()
+ args_arg = None
+ keywords_arg = None
+ if args and args[-1].startswith('**'):
+ keywords_arg = args[-1][2:]
+ del args[-1]
+ if args and args[-1].startswith('*'):
+ args_arg = args[-1][1:]
+ del args[-1]
+ if is_constructor:
+ args.insert(0, definition_info.args_with_defaults[0][0])
+ return CallInfo(info.get_function_name(), args, keywords, args_arg,
+ keywords_arg, is_method_call or is_classmethod,
+ is_constructor)
+
+ @staticmethod
+ def _is_method_call(primary, pyname):
+ return primary is not None and \
+ isinstance(primary.get_object().get_type(),
+ rope.base.pyobjects.PyClass) and \
+ CallInfo._is_method(pyname)
+
+ @staticmethod
+ def _is_class(pyname):
+ return pyname is not None and \
+ isinstance(pyname.get_object(),
+ rope.base.pyobjects.PyClass)
+
+ @staticmethod
+ def _is_method(pyname):
+ if pyname is not None and \
+ isinstance(pyname.get_object(), rope.base.pyobjects.PyFunction):
+ return pyname.get_object().get_kind() == 'method'
+ return False
+
+ @staticmethod
+ def _is_classmethod(pyname):
+ if pyname is not None and \
+ isinstance(pyname.get_object(), rope.base.pyobjects.PyFunction):
+ return pyname.get_object().get_kind() == 'classmethod'
+ return False
+
+
+class ArgumentMapping(object):
+
+ def __init__(self, definition_info, call_info):
+ self.call_info = call_info
+ self.param_dict = {}
+ self.keyword_args = []
+ self.args_arg = []
+ for index, value in enumerate(call_info.args):
+ if index < len(definition_info.args_with_defaults):
+ name = definition_info.args_with_defaults[index][0]
+ self.param_dict[name] = value
+ else:
+ self.args_arg.append(value)
+ for name, value in call_info.keywords:
+ index = -1
+ for pair in definition_info.args_with_defaults:
+ if pair[0] == name:
+ self.param_dict[name] = value
+ break
+ else:
+ self.keyword_args.append((name, value))
+
+ def to_call_info(self, definition_info):
+ args = []
+ keywords = []
+ for index in range(len(definition_info.args_with_defaults)):
+ name = definition_info.args_with_defaults[index][0]
+ if name in self.param_dict:
+ args.append(self.param_dict[name])
+ else:
+ for i in range(index, len(definition_info.args_with_defaults)):
+ name = definition_info.args_with_defaults[i][0]
+ if name in self.param_dict:
+ keywords.append((name, self.param_dict[name]))
+ break
+ args.extend(self.args_arg)
+ keywords.extend(self.keyword_args)
+ return CallInfo(self.call_info.function_name, args, keywords,
+ self.call_info.args_arg, self.call_info.keywords_arg,
+ self.call_info.implicit_arg,
+ self.call_info.constructor)
+
+
+class _FunctionParser(object):
+
+ def __init__(self, call, implicit_arg, is_lambda=False):
+ self.call = call
+ self.implicit_arg = implicit_arg
+ self.word_finder = worder.Worder(self.call)
+ if is_lambda:
+ self.last_parens = self.call.rindex(':')
+ else:
+ self.last_parens = self.call.rindex(')')
+ self.first_parens = self.word_finder._find_parens_start(
+ self.last_parens)
+
+ def get_parameters(self):
+ args, keywords = self.word_finder.get_parameters(self.first_parens,
+ self.last_parens)
+ if self.is_called_as_a_method():
+ instance = self.call[:self.call.rindex('.', 0, self.first_parens)]
+ args.insert(0, instance.strip())
+ return args, keywords
+
+ def get_instance(self):
+ if self.is_called_as_a_method():
+ return self.word_finder.get_primary_at(
+ self.call.rindex('.', 0, self.first_parens) - 1)
+
+ def get_function_name(self):
+ if self.is_called_as_a_method():
+ return self.word_finder.get_word_at(self.first_parens - 1)
+ else:
+ return self.word_finder.get_primary_at(self.first_parens - 1)
+
+ def is_called_as_a_method(self):
+ return self.implicit_arg and '.' in self.call[:self.first_parens]

Powered by Google App Engine
This is Rietveld 408576698