Commits

Anonymous committed b362662

inline: added InlineParameter class

  • Participants
  • Parent commits b6359e8

Comments (0)

Files changed (2)

File rope/refactor/inline.py

 import rope.refactor.functionutils
 from rope.base import pynames, pyobjects, codeanalyze, taskhandle, evaluate, worder
 from rope.base.change import ChangeSet, ChangeContents
-from rope.refactor import occurrences, rename, sourceutils, importutils, move
+from rope.refactor import (occurrences, rename, sourceutils,
+                           importutils, move, change_signature)
 
 
 def create_inline(project, resource, offset):
             'Inline refactoring should be performed on a method/local variable.')
     if isinstance(pyname, pynames.AssignedName):
         return InlineVariable(project, resource, offset)
-    elif isinstance(pyname.get_object(), pyobjects.PyFunction):
+    if isinstance(pyname, pynames.ParameterName):
+        return InlineParameter(project, resource, offset)
+    if isinstance(pyname.get_object(), pyobjects.PyFunction):
         return InlineMethod(project, resource, offset)
     else:
         raise rope.base.exceptions.RefactoringError(
         self.name = range_finder.get_word_at(offset)
         self.offset = offset
 
-    def get_changes(self, remove=True, only_current=False,
-                    task_handle=taskhandle.NullTaskHandle()):
-        """Get the changes this refactoring makes
-
-        If `remove` is `False` the definition will not be removed.  If
-        `only_current` is `True`, the the current occurrence will be
-        inlined, only.
-
-        """
+    def get_changes(self, *args, **kwds):
+        pass
 
     def get_kind(self):
-        """Return either 'variable' or 'method'"""
+        """Return either 'variable', 'method' or 'parameter'"""
 
 
 class InlineMethod(_Inliner):
 
     def get_changes(self, remove=True, only_current=False, resources=None,
                     task_handle=taskhandle.NullTaskHandle()):
+        """Get the changes this refactoring makes
+
+        If `remove` is `False` the definition will not be removed.  If
+        `only_current` is `True`, the the current occurrence will be
+        inlined, only.
+        """
         changes = ChangeSet('Inline method <%s>' % self.name)
         if resources is None:
             resources = self.pycore.get_python_files()
         return 'variable'
 
 
+class InlineParameter(_Inliner):
+
+    def __init__(self, *args, **kwds):
+        super(InlineParameter, self).__init__(*args, **kwds)
+        pymodule, lineno = self.pyname.get_definition_location()
+        resource = pymodule.get_resource()
+        start = pymodule.logical_lines.logical_line_in(lineno)[0]
+        start_offset = pymodule.lines.get_line_start(start)
+        def_ = pymodule.source_code.index('def', start_offset)
+        offset = def_ + 4
+        while pymodule.source_code[offset].isspace():
+            offset += 1
+
+        index = self.pyname.index
+        self.changers = [change_signature.ArgumentDefaultInliner(index)]
+        self.signature = change_signature.ChangeSignature(
+            self.project, resource, offset)
+
+    def get_changes(self, **kwds):
+        return self.signature.get_changes(self.changers, **kwds)
+
+    def get_kind(self):
+        return 'parameter'
+
+
 def _join_lines(lines):
     definition_lines = []
     for unchanged_line in lines:

File ropetest/refactor/inlinetest.py

         refactored = self._inline(code, code.index('a_var') + 1)
 
     @testutils.assert_raises(rope.base.exceptions.RefactoringError)
-    def test_on_parameters(self):
-        code = 'def a_func(a_param):\n    pass\n'
-        refactored = self._inline(code, code.index('a_param') + 1)
-
-    @testutils.assert_raises(rope.base.exceptions.RefactoringError)
     def test_tuple_assignments(self):
         code = 'a_var, another_var = (20, 30)\n'
         refactored = self._inline(code, code.index('a_var') + 1)
         self._inline2(self.mod, self.mod.read().index('a_func') + 1)
 
     def test_function_parameters_and_returns_in_other_functions(self):
-        self.mod.write('def a_func(param1, param2):\n    return param1 + param2\n'
-                       'range(a_func(20, param2=abs(10)))\n')
+        code = 'def a_func(param1, param2):\n' \
+               '    return param1 + param2\n' \
+               'range(a_func(20, param2=abs(10)))\n'
+        self.mod.write(code)
         self._inline2(self.mod, self.mod.read().index('a_func') + 1)
-        self.assertEquals('range(20 + abs(10))\n',
-                          self.mod.read())
+        self.assertEquals('range(20 + abs(10))\n', self.mod.read())
 
     @testutils.assert_raises(rope.base.exceptions.RefactoringError)
     def test_function_references_other_than_call(self):
         refactored = self._inline(code, code.rindex('f'))
         self.assertEquals('var = 1\n', refactored)
 
-    # XXX: funcutils fails on overlapping logical lines
     def test_inlining_one_line_functions_with_breaks(self):
         code = 'def f(\np): return p\nvar = f(1)\n'
         refactored = self._inline(code, code.rindex('f'))
         self.assertEquals('', self.mod.read())
         self.assertEquals('import mod\nmod.a_func()\n', mod1.read())
 
+    def test_inlining_parameters(self):
+        code = 'def f(p=1):\n    pass\nf()\n'
+        result = self._inline(code, code.index('p'))
+        self.assertEquals('def f(p=1):\n    pass\nf(1)\n', result)
+
 
 def suite():
     result = unittest.TestSuite()