mirror of
https://github.com/davidhalter/jedi.git
synced 2026-02-01 20:45:25 +08:00
Make refactoring diff path a relative path to the project path
This commit is contained in:
@@ -547,7 +547,7 @@ class Script(object):
|
||||
|
||||
def _rename(self, line, column, new_name): # Python 2...
|
||||
definitions = self.get_references(line, column, include_builtins=False)
|
||||
return refactoring.rename(self._inference_state.grammar, definitions, new_name)
|
||||
return refactoring.rename(self._inference_state, definitions, new_name)
|
||||
|
||||
@no_py2_support
|
||||
@validate_line_column
|
||||
@@ -569,7 +569,7 @@ class Script(object):
|
||||
until_column = len(self._code_lines[until_line - 1])
|
||||
until_pos = until_line, until_column
|
||||
return extract_variable(
|
||||
self._inference_state.grammar, self.path, self._module_node,
|
||||
self._inference_state, self.path, self._module_node,
|
||||
new_name, (line, column), until_pos
|
||||
)
|
||||
|
||||
@@ -602,7 +602,7 @@ class Script(object):
|
||||
Inlines a variable under the cursor.
|
||||
"""
|
||||
names = [d._name for d in self.get_references(line, column, include_builtins=True)]
|
||||
return refactoring.inline(self._inference_state.grammar, names)
|
||||
return refactoring.inline(self._inference_state, names)
|
||||
|
||||
|
||||
class Interpreter(Script):
|
||||
|
||||
@@ -14,8 +14,9 @@ EXPRESSION_PARTS = (
|
||||
|
||||
|
||||
class ChangedFile(object):
|
||||
def __init__(self, grammar, from_path, to_path, module_node, node_to_str_map):
|
||||
self._grammar = grammar
|
||||
def __init__(self, inference_state, from_path, to_path,
|
||||
module_node, node_to_str_map):
|
||||
self._inference_state = inference_state
|
||||
self._from_path = from_path
|
||||
self._to_path = to_path
|
||||
self._module_node = module_node
|
||||
@@ -24,17 +25,18 @@ class ChangedFile(object):
|
||||
def get_diff(self):
|
||||
old_lines = split_lines(self._module_node.get_code(), keepends=True)
|
||||
new_lines = split_lines(self.get_new_code(), keepends=True)
|
||||
project_path = self._inference_state.project._path
|
||||
diff = difflib.unified_diff(
|
||||
old_lines, new_lines,
|
||||
fromfile=relpath(self._from_path),
|
||||
tofile=relpath(self._to_path),
|
||||
fromfile=relpath(self._from_path, project_path),
|
||||
tofile=relpath(self._to_path, project_path),
|
||||
)
|
||||
# Apparently there's a space at the end of the diff - for whatever
|
||||
# reason.
|
||||
return ''.join(diff).rstrip(' ')
|
||||
|
||||
def get_new_code(self):
|
||||
return self._grammar.refactor(self._module_node, self._node_to_str_map)
|
||||
return self._inference_state.grammar.refactor(self._module_node, self._node_to_str_map)
|
||||
|
||||
def apply(self):
|
||||
if self._from_path is None:
|
||||
@@ -50,15 +52,14 @@ class ChangedFile(object):
|
||||
|
||||
|
||||
class Refactoring(object):
|
||||
def __init__(self, grammar, file_to_node_changes, renames=()):
|
||||
self._grammar = grammar
|
||||
def __init__(self, inference_state, file_to_node_changes, renames=()):
|
||||
self._inference_state = inference_state
|
||||
self._renames = renames
|
||||
self._file_to_node_changes = file_to_node_changes
|
||||
|
||||
def get_changed_files(self):
|
||||
"""
|
||||
Returns a path to ``ChangedFile`` map. The files can be used
|
||||
``Dict[str
|
||||
Returns a path to ``ChangedFile`` map.
|
||||
"""
|
||||
def calculate_to_path(p):
|
||||
if p is None:
|
||||
@@ -71,7 +72,7 @@ class Refactoring(object):
|
||||
renames = self.get_renames()
|
||||
return {
|
||||
path: ChangedFile(
|
||||
self._grammar,
|
||||
self._inference_state,
|
||||
from_path=path,
|
||||
to_path=calculate_to_path(path),
|
||||
module_node=next(iter(map_)).get_root_node(),
|
||||
@@ -89,8 +90,10 @@ class Refactoring(object):
|
||||
|
||||
def get_diff(self):
|
||||
text = ''
|
||||
project_path = self._inference_state.project._path
|
||||
for from_, to in self.get_renames():
|
||||
text += 'rename from %s\nrename to %s\n' % (relpath(from_), relpath(to))
|
||||
text += 'rename from %s\nrename to %s\n' \
|
||||
% (relpath(from_, project_path), relpath(to, project_path))
|
||||
|
||||
return text + ''.join(f.get_diff() for f in self.get_changed_files().values())
|
||||
|
||||
@@ -115,7 +118,7 @@ def _calculate_rename(path, new_name):
|
||||
return path, join(dir_, new_name + ending)
|
||||
|
||||
|
||||
def rename(grammar, definitions, new_name):
|
||||
def rename(inference_state, definitions, new_name):
|
||||
file_renames = set()
|
||||
file_tree_name_map = {}
|
||||
|
||||
@@ -132,10 +135,10 @@ def rename(grammar, definitions, new_name):
|
||||
if tree_name is not None:
|
||||
fmap = file_tree_name_map.setdefault(d.module_path, {})
|
||||
fmap[tree_name] = tree_name.prefix + new_name
|
||||
return Refactoring(grammar, file_tree_name_map, file_renames)
|
||||
return Refactoring(inference_state, file_tree_name_map, file_renames)
|
||||
|
||||
|
||||
def inline(grammar, names):
|
||||
def inline(inference_state, names):
|
||||
if not names:
|
||||
raise RefactoringError("There is no name under the cursor")
|
||||
if any(n.api_type == 'module' for n in names):
|
||||
@@ -212,7 +215,7 @@ def inline(grammar, names):
|
||||
if next_leaf.prefix.strip(' \t') == '' \
|
||||
and (next_leaf.type == 'newline' or next_leaf == ';'):
|
||||
changes[next_leaf] = ''
|
||||
return Refactoring(grammar, file_to_node_changes)
|
||||
return Refactoring(inference_state, file_to_node_changes)
|
||||
|
||||
|
||||
def _remove_indent_of_prefix(prefix):
|
||||
|
||||
@@ -16,7 +16,7 @@ _VARIABLE_EXCTRACTABLE = EXPRESSION_PARTS + \
|
||||
'keyword name number string fstring').split()
|
||||
|
||||
|
||||
def extract_variable(grammar, path, module_node, name, pos, until_pos):
|
||||
def extract_variable(inference_state, path, module_node, name, pos, until_pos):
|
||||
nodes = _find_nodes(module_node, pos, until_pos)
|
||||
debug.dbg('Extracting nodes: %s', nodes)
|
||||
|
||||
@@ -26,7 +26,7 @@ def extract_variable(grammar, path, module_node, name, pos, until_pos):
|
||||
|
||||
generated_code = name + ' = ' + _expression_nodes_to_string(nodes)
|
||||
file_to_node_changes = {path: _replace(nodes, name, generated_code, pos)}
|
||||
return Refactoring(grammar, file_to_node_changes)
|
||||
return Refactoring(inference_state, file_to_node_changes)
|
||||
|
||||
|
||||
def _is_expression_with_error(nodes):
|
||||
@@ -289,7 +289,7 @@ def extract_function(inference_state, path, module_context, name, pos, until_pos
|
||||
if not is_expression:
|
||||
replacement_dct[after_leaf] = second + after_leaf.value
|
||||
file_to_node_changes = {path: replacement_dct}
|
||||
return Refactoring(inference_state.grammar, file_to_node_changes)
|
||||
return Refactoring(inference_state, file_to_node_changes)
|
||||
|
||||
|
||||
def _check_for_non_extractables(nodes):
|
||||
|
||||
@@ -39,8 +39,8 @@ foobarb: int = 1
|
||||
#? 5
|
||||
test(foobarb)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,3 @@
|
||||
-foobarb: int = 1
|
||||
#? 5
|
||||
@@ -69,15 +69,15 @@ from import_tree import some_mod
|
||||
#? 20
|
||||
test(x, some_mod. inline_var.conjugate)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,4 @@
|
||||
from import_tree import some_mod
|
||||
#? 20
|
||||
-test(x, some_mod. inline_var.conjugate)
|
||||
+test(x, (5 + 3).conjugate)
|
||||
--- refactor/import_tree/some_mod.py
|
||||
+++ refactor/import_tree/some_mod.py
|
||||
--- import_tree/some_mod.py
|
||||
+++ import_tree/some_mod.py
|
||||
@@ -1,4 +1,3 @@
|
||||
foobar = 3
|
||||
|
||||
@@ -107,8 +107,8 @@ def test():
|
||||
a = (30 + b, c) + 1
|
||||
return test(100, a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,5 +1,4 @@
|
||||
def test():
|
||||
#? 4
|
||||
@@ -121,8 +121,8 @@ if 1:
|
||||
a = 1, 2
|
||||
return test(100, a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,5 +1,4 @@
|
||||
if 1:
|
||||
#? 4
|
||||
@@ -134,8 +134,8 @@ a = 1+2
|
||||
#? 11
|
||||
test(100 * a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,3 @@
|
||||
-a = 1+2
|
||||
#? 11
|
||||
@@ -146,8 +146,8 @@ a = 1+2
|
||||
#? 11
|
||||
(x, 100 * a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,3 @@
|
||||
-a = 1+2
|
||||
#? 11
|
||||
@@ -159,8 +159,8 @@ a = 1+2
|
||||
#? 9
|
||||
(100 ** a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,5 +1,4 @@
|
||||
x
|
||||
-a = 1+2
|
||||
@@ -173,8 +173,8 @@ a = 1+2
|
||||
#? 5
|
||||
test(a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,5 +1,4 @@
|
||||
x
|
||||
-a = 1+2
|
||||
@@ -186,8 +186,8 @@ a = 1+2
|
||||
#? 9
|
||||
test(3, a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,3 @@
|
||||
-a = 1+2
|
||||
#? 9
|
||||
@@ -198,8 +198,8 @@ a = 1|2
|
||||
#? 5
|
||||
(3, a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,3 @@
|
||||
-a = 1|2
|
||||
#? 5
|
||||
@@ -210,8 +210,8 @@ a = 1 and 2 # foo
|
||||
#? 9
|
||||
(3, 3 * a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-a = 1 and 2 # foo
|
||||
+ # foo
|
||||
@@ -223,8 +223,8 @@ a = 1, 2 ; b = 3
|
||||
#? 9
|
||||
(3, 3 == a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-a = 1, 2 ; b = 3
|
||||
+ b = 3
|
||||
@@ -236,8 +236,8 @@ a = 1 + 2
|
||||
#? 0
|
||||
a.conjugate
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/inline.py
|
||||
+++ refactor/inline.py
|
||||
--- inline.py
|
||||
+++ inline.py
|
||||
@@ -1,4 +1,3 @@
|
||||
-a = 1 + 2
|
||||
#? 0
|
||||
|
||||
@@ -15,8 +15,8 @@ def test1():
|
||||
AssertionError
|
||||
return test1, test1.not_existing
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,6 +1,6 @@
|
||||
-def test1():
|
||||
+def blabla():
|
||||
@@ -31,8 +31,8 @@ undefined_var
|
||||
#? 0 {'new_name': 'lala'}
|
||||
undefined_var
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,4 +1,4 @@
|
||||
undefined_var
|
||||
#? 0 {'new_name': 'lala'}
|
||||
@@ -47,8 +47,8 @@ def y():
|
||||
some_var = 3
|
||||
some_var
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,7 +1,7 @@
|
||||
def x():
|
||||
#? 7 {'new_name': 'v'}
|
||||
@@ -67,8 +67,8 @@ mykeywordparam1(1)
|
||||
mykeywordparam1(param1=3)
|
||||
mykeywordparam1(x, param1=2)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,7 +1,7 @@
|
||||
#? 22 {'new_name': 'lala'}
|
||||
-def mykeywordparam1(param1):
|
||||
@@ -88,8 +88,8 @@ mykeywordparam2(param1=3)
|
||||
#? 22 {'new_name': 'lala'}
|
||||
mykeywordparam2(x, param1=2)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,7 +1,7 @@
|
||||
-def mykeywordparam2(param1):
|
||||
- str(param1)
|
||||
@@ -106,15 +106,15 @@ from import_tree.some_mod import foobar
|
||||
#? 0 {'new_name': 'renamed'}
|
||||
foobar
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/import_tree/some_mod.py
|
||||
+++ refactor/import_tree/some_mod.py
|
||||
--- import_tree/some_mod.py
|
||||
+++ import_tree/some_mod.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-foobar = 3
|
||||
+renamed = 3
|
||||
|
||||
inline_var = 5 + 3
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-from import_tree.some_mod import foobar
|
||||
+from import_tree.some_mod import renamed
|
||||
@@ -126,10 +126,10 @@ from import_tree import some_mod
|
||||
#? 0 {'new_name': 'renamedm'}
|
||||
some_mod
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
rename from refactor/import_tree/some_mod.py
|
||||
rename to refactor/import_tree/renamedm.py
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
rename from import_tree/some_mod.py
|
||||
rename to import_tree/renamedm.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-from import_tree import some_mod
|
||||
+from import_tree import renamedm
|
||||
@@ -141,8 +141,8 @@ rename to refactor/import_tree/renamedm.py
|
||||
import undefined_import
|
||||
haha( undefined_import)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,4 +1,4 @@
|
||||
#? 20 {'new_name': 'lala'}
|
||||
-import undefined_import
|
||||
@@ -153,24 +153,24 @@ haha( undefined_import)
|
||||
#? 31 {'new_name': 'renamedm'}
|
||||
from import_tree.pkgx import pkgx
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- refactor/import_tree/pkgx/__init__.py
|
||||
+++ refactor/import_tree/pkgx/__init__.py
|
||||
--- import_tree/pkgx/__init__.py
|
||||
+++ import_tree/pkgx/__init__.py
|
||||
@@ -1,3 +1,3 @@
|
||||
-def pkgx():
|
||||
+def renamedm():
|
||||
pass
|
||||
--- refactor/import_tree/pkgx/__init__.pyi
|
||||
+++ refactor/import_tree/pkgx/__init__.pyi
|
||||
--- import_tree/pkgx/__init__.pyi
|
||||
+++ import_tree/pkgx/__init__.pyi
|
||||
@@ -1,2 +1,2 @@
|
||||
-def pkgx() -> int: ...
|
||||
+def renamedm() -> int: ...
|
||||
--- refactor/import_tree/pkgx/mod.pyi
|
||||
+++ refactor/import_tree/pkgx/mod.pyi
|
||||
--- import_tree/pkgx/mod.pyi
|
||||
+++ import_tree/pkgx/mod.pyi
|
||||
@@ -1,2 +1,2 @@
|
||||
-from . import pkgx
|
||||
+from . import renamedm
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,3 +1,3 @@
|
||||
#? 31 {'new_name': 'renamedm'}
|
||||
-from import_tree.pkgx import pkgx
|
||||
@@ -179,15 +179,15 @@ from import_tree.pkgx import pkgx
|
||||
#? 18 {'new_name': 'renamedp'}
|
||||
from import_tree.pkgx
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
rename from refactor/import_tree/pkgx
|
||||
rename to refactor/import_tree/renamedp
|
||||
--- refactor/import_tree/pkgx/mod2.py
|
||||
+++ refactor/import_tree/renamedp/mod2.py
|
||||
rename from import_tree/pkgx
|
||||
rename to import_tree/renamedp
|
||||
--- import_tree/pkgx/mod2.py
|
||||
+++ import_tree/renamedp/mod2.py
|
||||
@@ -1,2 +1,2 @@
|
||||
-from .. import pkgx
|
||||
+from .. import renamedp
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,3 +1,3 @@
|
||||
#? 18 {'new_name': 'renamedp'}
|
||||
-from import_tree.pkgx
|
||||
@@ -200,31 +200,31 @@ else:
|
||||
#? 4 {'new_name': 'rename'}
|
||||
pkgx
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
rename from refactor/import_tree/pkgx
|
||||
rename to refactor/import_tree/rename
|
||||
--- refactor/import_tree/pkgx/__init__.py
|
||||
+++ refactor/import_tree/rename/__init__.py
|
||||
rename from import_tree/pkgx
|
||||
rename to import_tree/rename
|
||||
--- import_tree/pkgx/__init__.py
|
||||
+++ import_tree/rename/__init__.py
|
||||
@@ -1,3 +1,3 @@
|
||||
-def pkgx():
|
||||
+def rename():
|
||||
pass
|
||||
--- refactor/import_tree/pkgx/__init__.pyi
|
||||
+++ refactor/import_tree/rename/__init__.pyi
|
||||
--- import_tree/pkgx/__init__.pyi
|
||||
+++ import_tree/rename/__init__.pyi
|
||||
@@ -1,2 +1,2 @@
|
||||
-def pkgx() -> int: ...
|
||||
+def rename() -> int: ...
|
||||
--- refactor/import_tree/pkgx/mod.pyi
|
||||
+++ refactor/import_tree/rename/mod.pyi
|
||||
--- import_tree/pkgx/mod.pyi
|
||||
+++ import_tree/rename/mod.pyi
|
||||
@@ -1,2 +1,2 @@
|
||||
-from . import pkgx
|
||||
+from . import rename
|
||||
--- refactor/import_tree/pkgx/mod2.py
|
||||
+++ refactor/import_tree/rename/mod2.py
|
||||
--- import_tree/pkgx/mod2.py
|
||||
+++ import_tree/rename/mod2.py
|
||||
@@ -1,2 +1,2 @@
|
||||
-from .. import pkgx
|
||||
+from .. import rename
|
||||
--- refactor/rename.py
|
||||
+++ refactor/rename.py
|
||||
--- rename.py
|
||||
+++ rename.py
|
||||
@@ -1,7 +1,7 @@
|
||||
if random_undefined_variable:
|
||||
- from import_tree.pkgx import pkgx
|
||||
|
||||
@@ -41,16 +41,16 @@ def test_rename_mod(Script, dir_with_content):
|
||||
assert refactoring.get_changed_files()[p1].get_new_code() == expected_code
|
||||
|
||||
assert refactoring.get_diff() == dedent('''\
|
||||
rename from {dir}/modx.py
|
||||
rename to {dir}/modr.py
|
||||
--- {dir}/modx.py
|
||||
+++ {dir}/modr.py
|
||||
rename from modx.py
|
||||
rename to modr.py
|
||||
--- modx.py
|
||||
+++ modr.py
|
||||
@@ -1,3 +1,3 @@
|
||||
-import modx
|
||||
+import modr
|
||||
foo
|
||||
--- {dir}/some_script.py
|
||||
+++ {dir}/some_script.py
|
||||
--- some_script.py
|
||||
+++ some_script.py
|
||||
@@ -1,2 +1,2 @@
|
||||
-import modx; modx
|
||||
+import modr; modr
|
||||
|
||||
Reference in New Issue
Block a user