diff options
-rw-r--r-- | mesonbuild/rewriter.py | 53 | ||||
-rwxr-xr-x | run_unittests.py | 26 | ||||
-rw-r--r-- | test cases/rewrite/1 basic/meson.build | 2 | ||||
-rw-r--r-- | test cases/rewrite/1 basic/rmTgt.json | 12 | ||||
-rw-r--r-- | test cases/rewrite/2 subdirs/rmTgt.json | 7 |
5 files changed, 89 insertions, 11 deletions
diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index 6752189..a3e78af 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -251,8 +251,9 @@ rewriter_keys = { }, 'target': { 'target': (str, None, None), - 'operation': (str, None, ['src_add', 'src_rm', 'info']), + 'operation': (str, None, ['src_add', 'src_rm', 'tgt_rm', 'info']), 'sources': (list, [], None), + 'subdir': (str, '', None), 'debug': (bool, False, None) } } @@ -547,6 +548,14 @@ class Rewriter: if root not in self.modefied_nodes: self.modefied_nodes += [root] + elif cmd['operation'] == 'tgt_rm': + to_remove = self.find_assignment_node(target['node']) + if to_remove is None: + to_remove = target['node'] + self.to_remove_nodes += [to_remove] + mlog.log(' -- Removing target', mlog.green(cmd['target']), 'at', + mlog.yellow('{}:{}'.format(os.path.join(to_remove.subdir, environment.build_filename), to_remove.lineno))) + elif cmd['operation'] == 'info': # List all sources in the target src_list = [] @@ -570,20 +579,28 @@ class Rewriter: def apply_changes(self): assert(all(hasattr(x, 'lineno') and hasattr(x, 'colno') and hasattr(x, 'subdir') for x in self.modefied_nodes)) + assert(all(hasattr(x, 'lineno') and hasattr(x, 'colno') and hasattr(x, 'subdir') for x in self.to_remove_nodes)) assert(all(isinstance(x, (mparser.ArrayNode, mparser.FunctionNode)) for x in self.modefied_nodes)) + assert(all(isinstance(x, (mparser.ArrayNode, mparser.AssignmentNode, mparser.FunctionNode)) for x in self.to_remove_nodes)) # Sort based on line and column in reversed order - work_nodes = list(sorted(self.modefied_nodes, key=lambda x: x.lineno * 1000 + x.colno, reverse=True)) + work_nodes = [{'node': x, 'action': 'modify'} for x in self.modefied_nodes] + work_nodes += [{'node': x, 'action': 'rm'} for x in self.to_remove_nodes] + work_nodes = list(sorted(work_nodes, key=lambda x: x['node'].lineno * 1000 + x['node'].colno, reverse=True)) # Generating the new replacement string str_list = [] for i in work_nodes: - printer = AstPrinter() - i.accept(printer) - printer.post_process() + new_data = '' + if i['action'] == 'modify': + printer = AstPrinter() + i['node'].accept(printer) + printer.post_process() + new_data = printer.result.strip() data = { - 'file': os.path.join(i.subdir, environment.build_filename), - 'str': printer.result.strip(), - 'node': i + 'file': os.path.join(i['node'].subdir, environment.build_filename), + 'str': new_data, + 'node': i['node'], + 'action': i['action'] } str_list += [data] @@ -612,7 +629,7 @@ class Rewriter: } # Replace in source code - for i in str_list: + def remove_node(i): offsets = files[i['file']]['offsets'] raw = files[i['file']]['raw'] node = i['node'] @@ -623,7 +640,7 @@ class Rewriter: if isinstance(node, mparser.ArrayNode): if raw[end] != '[': mlog.warning('Internal error: expected "[" at {}:{} but got "{}"'.format(line, col, raw[end])) - continue + return counter = 1 while counter > 0: end += 1 @@ -632,6 +649,7 @@ class Rewriter: elif raw[end] == ']': counter -= 1 end += 1 + elif isinstance(node, mparser.FunctionNode): while raw[end] != '(': end += 1 @@ -644,8 +662,23 @@ class Rewriter: elif raw[end] == ')': counter -= 1 end += 1 + + # Only removal is supported for assignments + elif isinstance(node, mparser.AssignmentNode) and i['action'] == 'rm': + if isinstance(node.value, (mparser.ArrayNode, mparser.FunctionNode)): + remove_node({'file': i['file'], 'str': '', 'node': node.value, 'action': 'rm'}) + raw = files[i['file']]['raw'] + while raw[end] != '=': + end += 1 + end += 1 # Handle the '=' + while raw[end] in [' ', '\n', '\t']: + end += 1 + raw = files[i['file']]['raw'] = raw[:start] + i['str'] + raw[end:] + for i in str_list: + remove_node(i) + # Write the files back for key, val in files.items(): mlog.log('Rewriting', mlog.yellow(key)) diff --git a/run_unittests.py b/run_unittests.py index f63fc18..a0b3ed5 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5161,6 +5161,32 @@ class RewriterTests(BasePlatformTests): out = self.extract_test_data(out) self.assertDictEqual(list(out['target'].values())[0], expected) + def test_target_remove(self): + self.prime('1 basic') + self.rewrite(self.builddir, os.path.join(self.builddir, 'rmTgt.json')) + out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) + out = self.extract_test_data(out) + + expected = { + 'target': { + 'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileB.cpp', 'fileC.cpp']}, + 'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp', 'fileA.cpp']}, + 'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp', 'fileA.cpp']}, + 'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileB.cpp', 'fileC.cpp']}, + 'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp']}, + 'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'main.cpp', 'fileA.cpp']}, + 'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp', 'fileA.cpp']}, + } + } + self.assertDictEqual(out, expected) + + def test_target_remove_subdir(self): + self.prime('2 subdirs') + self.rewrite(self.builddir, os.path.join(self.builddir, 'rmTgt.json')) + out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) + out = self.extract_test_data(out) + self.assertDictEqual(out, {}) + def test_kwargs_info(self): self.prime('3 kwargs') out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) diff --git a/test cases/rewrite/1 basic/meson.build b/test cases/rewrite/1 basic/meson.build index 1bed0e1..920553d 100644 --- a/test cases/rewrite/1 basic/meson.build +++ b/test cases/rewrite/1 basic/meson.build @@ -15,4 +15,4 @@ exe5 = executable('trivialprog5', [src2, 'main.cpp']) exe6 = executable('trivialprog6', 'main.cpp', 'fileA.cpp') exe7 = executable('trivialprog7', 'fileB.cpp', src1, 'fileC.cpp') exe8 = executable('trivialprog8', src3) -exe9 = executable('trivialprog9', src4) +executable('trivialprog9', src4) diff --git a/test cases/rewrite/1 basic/rmTgt.json b/test cases/rewrite/1 basic/rmTgt.json new file mode 100644 index 0000000..9172296 --- /dev/null +++ b/test cases/rewrite/1 basic/rmTgt.json @@ -0,0 +1,12 @@ +[ + { + "type": "target", + "target": "trivialprog1", + "operation": "tgt_rm" + }, + { + "type": "target", + "target": "trivialprog9", + "operation": "tgt_rm" + } +]
\ No newline at end of file diff --git a/test cases/rewrite/2 subdirs/rmTgt.json b/test cases/rewrite/2 subdirs/rmTgt.json new file mode 100644 index 0000000..0e3949b --- /dev/null +++ b/test cases/rewrite/2 subdirs/rmTgt.json @@ -0,0 +1,7 @@ +[ + { + "type": "target", + "target": "something", + "operation": "tgt_rm" + } +]
\ No newline at end of file |