rewriter: Handle duplicate target

pull/4992/head
Daniel Mensinger 6 years ago
parent ff5e7eb104
commit e724fd5438
No known key found for this signature in database
GPG Key ID: 54DD94C131E277D4
  1. 3
      docs/markdown/Rewriter.md
  2. 5
      mesonbuild/ast/interpreter.py
  3. 7
      mesonbuild/ast/introspection.py
  4. 24
      mesonbuild/rewriter.py
  5. 9
      run_unittests.py
  6. 8
      test cases/rewrite/4 same name targets/addSrc.json
  7. 12
      test cases/rewrite/4 same name targets/info.json
  8. 6
      test cases/rewrite/4 same name targets/meson.build
  9. 3
      test cases/rewrite/4 same name targets/sub1/meson.build

@ -63,7 +63,8 @@ exe1 = executable('testExe', src)
In this case, `exe1` could also have been used for the target name. This is
possible because the rewriter also searches for assignments and unique meson
IDs, which can be acquired with introspection.
IDs, which can be acquired with introspection. If there are multiple targets
with the same name, meson will do nothing and print an error message.
For more information see the help output of the rewriter target command.

@ -51,6 +51,7 @@ class AstInterpreter(interpreterbase.InterpreterBase):
self.visitors = visitors
self.visited_subdirs = {}
self.assignments = {}
self.assign_vals = {}
self.reverse_assignment = {}
self.funcs.update({'project': self.func_do_nothing,
'test': self.func_do_nothing,
@ -161,7 +162,7 @@ class AstInterpreter(interpreterbase.InterpreterBase):
self.assignments[node.var_name] += [node.value] # Save a reference to the value node
if hasattr(node.value, 'ast_id'):
self.reverse_assignment[node.value.ast_id] = node
self.evaluate_statement(node.value) # Evaluate the value just in case
self.assign_vals[node.var_name] += [self.evaluate_statement(node.value)]
def evaluate_indexing(self, node):
return 0
@ -200,7 +201,7 @@ class AstInterpreter(interpreterbase.InterpreterBase):
self.assignments[node.var_name] = [node.value] # Save a reference to the value node
if hasattr(node.value, 'ast_id'):
self.reverse_assignment[node.value.ast_id] = node
self.evaluate_statement(node.value) # Evaluate the value just in case
self.assign_vals[node.var_name] = [self.evaluate_statement(node.value)] # Evaluate the value just in case
def flatten_args(self, args, include_unknown_args: bool = False):
# Resolve mparser.ArrayNode if needed

@ -194,7 +194,7 @@ class IntrospectionInterpreter(AstInterpreter):
empty_sources = [] # Passing the unresolved sources list causes errors
target = targetclass(name, self.subdir, self.subproject, is_cross, empty_sources, objects, self.environment, kwargs_reduced)
self.targets += [{
new_target = {
'name': target.get_basename(),
'id': target.get_id(),
'type': target.get_typename(),
@ -206,9 +206,10 @@ class IntrospectionInterpreter(AstInterpreter):
'sources': source_nodes,
'kwargs': kwargs,
'node': node,
}]
}
return
self.targets += [new_target]
return new_target
def build_library(self, node, args, kwargs):
default_library = self.coredata.get_builtin_option('default_library')

@ -379,23 +379,31 @@ class Rewriter:
sys.stderr.write(json.dumps(self.info_dump, indent=2))
def find_target(self, target: str):
def check_list(name: str):
def check_list(name: str) -> List[BaseNode]:
result = []
for i in self.interpreter.targets:
if name == i['name'] or name == i['id']:
return i
return None
result += [i]
return result
tgt = check_list(target)
if tgt is not None:
return tgt
targets = check_list(target)
if targets:
if len(targets) == 1:
return targets[0]
else:
mlog.error('There are multiple targets matching', mlog.bold(target))
for i in targets:
mlog.error(' -- Target name', mlog.bold(i['name']), 'with ID', mlog.bold(i['id']))
mlog.error('Please try again with the unique ID of the target --> skipping')
return None
# Check the assignments
tgt = None
if target in self.interpreter.assignments:
node = self.interpreter.assignments[target][0]
if isinstance(node, FunctionNode):
if node.func_name in ['executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library', 'both_libraries']:
name = self.interpreter.flatten_args(node.args)[0]
tgt = check_list(name)
tgt = self.interpreter.assign_vals[target][0]
return tgt

@ -5401,6 +5401,15 @@ class RewriterTests(BasePlatformTests):
}
self.assertDictEqual(out, expected)
def test_target_same_name_skip(self):
self.prime('4 same name targets')
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'addSrc.json'))
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))
expected = {'name': 'myExe', 'sources': ['main.cpp']}
self.assertEqual(len(out['target']), 2)
for _, val in out['target'].items():
self.assertDictEqual(expected, val)
def test_kwargs_info(self):
self.prime('3 kwargs')
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))

@ -0,0 +1,8 @@
[
{
"type": "target",
"target": "myExe",
"operation": "src_add",
"sources": ["a1.cpp", "a2.cpp"]
}
]

@ -0,0 +1,12 @@
[
{
"type": "target",
"target": "exe1",
"operation": "info"
},
{
"type": "target",
"target": "exe2",
"operation": "info"
}
]

@ -0,0 +1,6 @@
project('rewrite same name targets', 'cpp')
src1 = ['main.cpp']
exe1 = executable('myExe', src1)
subdir('sub1')

@ -0,0 +1,3 @@
src2 = ['main.cpp']
exe2 = executable('myExe', src2)
Loading…
Cancel
Save