Merge pull request #4818 from xclaesse/location

Pass location to many warning messages
pull/4824/head
Jussi Pakkanen 6 years ago committed by GitHub
commit 2502f97913
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      mesonbuild/interpreter.py
  2. 43
      mesonbuild/interpreterbase.py

@ -743,7 +743,8 @@ class BuildTargetHolder(TargetHolder):
mlog.warning('extract_all_objects called without setting recursive ' mlog.warning('extract_all_objects called without setting recursive '
'keyword argument. Meson currently defaults to ' 'keyword argument. Meson currently defaults to '
'non-recursive to maintain backward compatibility but ' 'non-recursive to maintain backward compatibility but '
'the default will be changed in the future.') 'the default will be changed in the future.',
location=self.current_node)
return GeneratedObjectsHolder(gobjs) return GeneratedObjectsHolder(gobjs)
@noPosargs @noPosargs
@ -1597,7 +1598,7 @@ ModuleState = namedtuple('ModuleState', [
'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment', 'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment',
'project_name', 'project_version', 'backend', 'compilers', 'targets', 'project_name', 'project_version', 'backend', 'compilers', 'targets',
'data', 'headers', 'man', 'global_args', 'project_args', 'build_machine', 'data', 'headers', 'man', 'global_args', 'project_args', 'build_machine',
'host_machine', 'target_machine']) 'host_machine', 'target_machine', 'current_node'])
class ModuleHolder(InterpreterObject, ObjectHolder): class ModuleHolder(InterpreterObject, ObjectHolder):
def __init__(self, modname, module, interpreter): def __init__(self, modname, module, interpreter):
@ -1640,6 +1641,7 @@ class ModuleHolder(InterpreterObject, ObjectHolder):
build_machine=self.interpreter.builtin['build_machine'].held_object, build_machine=self.interpreter.builtin['build_machine'].held_object,
host_machine=self.interpreter.builtin['host_machine'].held_object, host_machine=self.interpreter.builtin['host_machine'].held_object,
target_machine=self.interpreter.builtin['target_machine'].held_object, target_machine=self.interpreter.builtin['target_machine'].held_object,
current_node=self.current_node
) )
if self.held_object.is_snippet(method_name): if self.held_object.is_snippet(method_name):
value = fn(self.interpreter, state, args, kwargs) value = fn(self.interpreter, state, args, kwargs)
@ -2365,7 +2367,8 @@ external dependencies (including libraries) must go to "dependencies".''')
if os.path.isabs(dirname): if os.path.isabs(dirname):
raise InterpreterException('Subproject name must not be an absolute path.') raise InterpreterException('Subproject name must not be an absolute path.')
if has_path_sep(dirname): if has_path_sep(dirname):
mlog.warning('Subproject name has a path separator. This may cause unexpected behaviour.') mlog.warning('Subproject name has a path separator. This may cause unexpected behaviour.',
location=self.current_node)
if dirname in self.subproject_stack: if dirname in self.subproject_stack:
fullstack = self.subproject_stack + [dirname] fullstack = self.subproject_stack + [dirname]
incpath = ' => '.join(fullstack) incpath = ' => '.join(fullstack)
@ -2469,7 +2472,8 @@ external dependencies (including libraries) must go to "dependencies".''')
mlog.warning('Option {0!r} of type {1!r} in subproject {2!r} cannot yield ' mlog.warning('Option {0!r} of type {1!r} in subproject {2!r} cannot yield '
'to parent option of type {3!r}, ignoring parent value. ' 'to parent option of type {3!r}, ignoring parent value. '
'Use -D{2}:{0}=value to set the value for this option manually' 'Use -D{2}:{0}=value to set the value for this option manually'
'.'.format(raw_optname, opt_type, self.subproject, popt_type)) '.'.format(raw_optname, opt_type, self.subproject, popt_type),
location=self.current_node)
return opt return opt
except KeyError: except KeyError:
pass pass
@ -2924,7 +2928,8 @@ external dependencies (including libraries) must go to "dependencies".''')
has_fallback = 'fallback' in kwargs has_fallback = 'fallback' in kwargs
if 'default_options' in kwargs and not has_fallback: if 'default_options' in kwargs and not has_fallback:
mlog.warning('The "default_options" keyworg argument does nothing without a "fallback" keyword argument.') mlog.warning('The "default_options" keyworg argument does nothing without a "fallback" keyword argument.',
location=self.current_node)
# writing just "dependency('')" is an error, because it can only fail # writing just "dependency('')" is an error, because it can only fail
if name == '' and required and not has_fallback: if name == '' and required and not has_fallback:
@ -2989,7 +2994,7 @@ external dependencies (including libraries) must go to "dependencies".''')
command_templ = '\nmeson wrap promote {}' command_templ = '\nmeson wrap promote {}'
for l in found: for l in found:
message.append(mlog.bold(command_templ.format(l[len(self.source_root) + 1:]))) message.append(mlog.bold(command_templ.format(l[len(self.source_root) + 1:])))
mlog.warning(*message) mlog.warning(*message, location=self.current_node)
def get_subproject_infos(self, kwargs): def get_subproject_infos(self, kwargs):
fbinfo = kwargs['fallback'] fbinfo = kwargs['fallback']
@ -3141,7 +3146,7 @@ external dependencies (including libraries) must go to "dependencies".''')
kwargs['input'] = self.source_strings_to_files(extract_as_list(kwargs, 'input')) kwargs['input'] = self.source_strings_to_files(extract_as_list(kwargs, 'input'))
except mesonlib.MesonException: except mesonlib.MesonException:
mlog.warning('''Custom target input \'%s\' can\'t be converted to File object(s). mlog.warning('''Custom target input \'%s\' can\'t be converted to File object(s).
This will become a hard error in the future.''' % kwargs['input']) This will become a hard error in the future.''' % kwargs['input'], location=self.current_node)
tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs), self) tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs), self)
self.add_target(name, tg.held_object) self.add_target(name, tg.held_object)
return tg return tg
@ -3799,7 +3804,8 @@ different subdirectory.
self.coredata.base_options['b_sanitize'].value != 'none'): self.coredata.base_options['b_sanitize'].value != 'none'):
mlog.warning('''Trying to use {} sanitizer on Clang with b_lundef. mlog.warning('''Trying to use {} sanitizer on Clang with b_lundef.
This will probably not work. This will probably not work.
Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_sanitize'].value)) Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_sanitize'].value),
location=self.current_node)
def evaluate_subproject_info(self, path_from_source_root, subproject_dirname): def evaluate_subproject_info(self, path_from_source_root, subproject_dirname):
depth = 0 depth = 0
@ -3993,7 +3999,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s
# path declarations. # path declarations.
if os.path.normpath(i).startswith(self.environment.get_source_dir()): if os.path.normpath(i).startswith(self.environment.get_source_dir()):
mlog.warning('''Building a path to the source dir is not supported. Use a relative path instead. mlog.warning('''Building a path to the source dir is not supported. Use a relative path instead.
This will become a hard error in the future.''') This will become a hard error in the future.''', location=self.current_node)
i = os.path.relpath(i, os.path.join(self.environment.get_source_dir(), self.subdir)) i = os.path.relpath(i, os.path.join(self.environment.get_source_dir(), self.subdir))
i = self.build_incdir_object([i]) i = self.build_incdir_object([i])
cleaned_items.append(i) cleaned_items.append(i)

@ -47,14 +47,14 @@ def _get_callee_args(wrapped_args, want_subproject=False):
if want_subproject and n == 2: if want_subproject and n == 2:
if hasattr(s, 'subproject'): if hasattr(s, 'subproject'):
# Interpreter base types have 2 args: self, node # Interpreter base types have 2 args: self, node
node_or_state = wrapped_args[1] node = wrapped_args[1]
# args and kwargs are inside the node # args and kwargs are inside the node
args = None args = None
kwargs = None kwargs = None
subproject = s.subproject subproject = s.subproject
elif hasattr(wrapped_args[1], 'subproject'): elif hasattr(wrapped_args[1], 'subproject'):
# Module objects have 2 args: self, interpreter # Module objects have 2 args: self, interpreter
node_or_state = wrapped_args[1] node = wrapped_args[1].current_node
# args and kwargs are inside the node # args and kwargs are inside the node
args = None args = None
kwargs = None kwargs = None
@ -63,7 +63,7 @@ def _get_callee_args(wrapped_args, want_subproject=False):
raise AssertionError('Unknown args: {!r}'.format(wrapped_args)) raise AssertionError('Unknown args: {!r}'.format(wrapped_args))
elif n == 3: elif n == 3:
# Methods on objects (*Holder, MesonMain, etc) have 3 args: self, args, kwargs # Methods on objects (*Holder, MesonMain, etc) have 3 args: self, args, kwargs
node_or_state = None # FIXME node = s.current_node
args = wrapped_args[1] args = wrapped_args[1]
kwargs = wrapped_args[2] kwargs = wrapped_args[2]
if want_subproject: if want_subproject:
@ -73,30 +73,32 @@ def _get_callee_args(wrapped_args, want_subproject=False):
subproject = s.interpreter.subproject subproject = s.interpreter.subproject
elif n == 4: elif n == 4:
# Meson functions have 4 args: self, node, args, kwargs # Meson functions have 4 args: self, node, args, kwargs
# Module functions have 4 args: self, state, args, kwargs; except, # Module functions have 4 args: self, state, args, kwargs
# PythonInstallation methods have self, interpreter, args, kwargs if isinstance(s, InterpreterBase):
node_or_state = wrapped_args[1] node = wrapped_args[1]
else:
node = wrapped_args[1].current_node
args = wrapped_args[2] args = wrapped_args[2]
kwargs = wrapped_args[3] kwargs = wrapped_args[3]
if want_subproject: if want_subproject:
if isinstance(s, InterpreterBase): if isinstance(s, InterpreterBase):
subproject = s.subproject subproject = s.subproject
else: else:
subproject = node_or_state.subproject subproject = wrapped_args[1].subproject
elif n == 5: elif n == 5:
# Module snippets have 5 args: self, interpreter, state, args, kwargs # Module snippets have 5 args: self, interpreter, state, args, kwargs
node_or_state = wrapped_args[2] node = wrapped_args[2].current_node
args = wrapped_args[3] args = wrapped_args[3]
kwargs = wrapped_args[4] kwargs = wrapped_args[4]
if want_subproject: if want_subproject:
subproject = node_or_state.subproject subproject = wrapped_args[2].subproject
else: else:
raise AssertionError('Unknown args: {!r}'.format(wrapped_args)) raise AssertionError('Unknown args: {!r}'.format(wrapped_args))
# Sometimes interpreter methods are called internally with None instead of # Sometimes interpreter methods are called internally with None instead of
# empty list/dict # empty list/dict
args = args if args is not None else [] args = args if args is not None else []
kwargs = kwargs if kwargs is not None else {} kwargs = kwargs if kwargs is not None else {}
return s, node_or_state, args, kwargs, subproject return s, node, args, kwargs, subproject
def flatten(args): def flatten(args):
if isinstance(args, mparser.StringNode): if isinstance(args, mparser.StringNode):
@ -164,19 +166,10 @@ class permittedKwargs:
def __call__(self, f): def __call__(self, f):
@wraps(f) @wraps(f)
def wrapped(*wrapped_args, **wrapped_kwargs): def wrapped(*wrapped_args, **wrapped_kwargs):
s, node_or_state, args, kwargs, _ = _get_callee_args(wrapped_args) s, node, args, kwargs, _ = _get_callee_args(wrapped_args)
loc = types.SimpleNamespace()
if hasattr(s, 'subdir'):
loc.subdir = s.subdir
loc.lineno = s.current_lineno
elif node_or_state and hasattr(node_or_state, 'subdir'):
loc.subdir = node_or_state.subdir
loc.lineno = node_or_state.current_lineno
else:
loc = None
for k in kwargs: for k in kwargs:
if k not in self.permitted: if k not in self.permitted:
mlog.warning('''Passed invalid keyword argument "{}".'''.format(k), location=loc) mlog.warning('''Passed invalid keyword argument "{}".'''.format(k), location=node)
mlog.warning('This will become a hard error in the future.') mlog.warning('This will become a hard error in the future.')
return f(*wrapped_args, **wrapped_kwargs) return f(*wrapped_args, **wrapped_kwargs)
return wrapped return wrapped
@ -320,6 +313,9 @@ class BreakRequest(BaseException):
class InterpreterObject: class InterpreterObject:
def __init__(self): def __init__(self):
self.methods = {} self.methods = {}
# Current node set during a method call. This can be used as location
# when printing a warning message during a method call.
self.current_node = None
def method_call(self, method_name, args, kwargs): def method_call(self, method_name, args, kwargs):
if method_name in self.methods: if method_name in self.methods:
@ -366,6 +362,9 @@ class InterpreterBase:
self.variables = {} self.variables = {}
self.argument_depth = 0 self.argument_depth = 0
self.current_lineno = -1 self.current_lineno = -1
# Current node set during a function call. This can be used as location
# when printing a warning message during a method call.
self.current_node = None
def load_root_meson_file(self): def load_root_meson_file(self):
mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename) mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename)
@ -759,6 +758,7 @@ The result of this is undefined and will become a hard error in a future Meson r
if not getattr(func, 'no-args-flattening', False): if not getattr(func, 'no-args-flattening', False):
posargs = flatten(posargs) posargs = flatten(posargs)
self.current_node = node
return func(node, posargs, kwargs) return func(node, posargs, kwargs)
else: else:
self.unknown_function_called(func_name) self.unknown_function_called(func_name)
@ -795,6 +795,7 @@ The result of this is undefined and will become a hard error in a future Meson r
return Disabler() return Disabler()
if method_name == 'extract_objects': if method_name == 'extract_objects':
self.validate_extraction(obj.held_object) self.validate_extraction(obj.held_object)
obj.current_node = node
return obj.method_call(method_name, args, kwargs) return obj.method_call(method_name, args, kwargs)
def bool_method_call(self, obj, method_name, args): def bool_method_call(self, obj, method_name, args):

Loading…
Cancel
Save