parser: use IdNode for function name and assignment name

pull/12152/head
Charles Brunet 2 years ago
parent 35936283d2
commit 306562b466
  1. 19
      mesonbuild/ast/interpreter.py
  2. 2
      mesonbuild/ast/introspection.py
  3. 16
      mesonbuild/ast/printer.py
  4. 4
      mesonbuild/ast/visitor.py
  5. 6
      mesonbuild/cargo/builder.py
  6. 6
      mesonbuild/cmake/interpreter.py
  7. 4
      mesonbuild/interpreter/interpreter.py
  8. 10
      mesonbuild/interpreterbase/interpreterbase.py
  9. 2
      mesonbuild/mintro.py
  10. 28
      mesonbuild/mparser.py
  11. 2
      mesonbuild/optinterpreter.py
  12. 14
      mesonbuild/rewriter.py

@ -254,10 +254,10 @@ class AstInterpreter(InterpreterBase):
def evaluate_plusassign(self, node: PlusAssignmentNode) -> None: def evaluate_plusassign(self, node: PlusAssignmentNode) -> None:
assert isinstance(node, PlusAssignmentNode) assert isinstance(node, PlusAssignmentNode)
# Cheat by doing a reassignment # Cheat by doing a reassignment
self.assignments[node.var_name] = node.value # Save a reference to the value node self.assignments[node.var_name.value] = node.value # Save a reference to the value node
if node.value.ast_id: if node.value.ast_id:
self.reverse_assignment[node.value.ast_id] = node self.reverse_assignment[node.value.ast_id] = node
self.assign_vals[node.var_name] = self.evaluate_statement(node.value) self.assign_vals[node.var_name.value] = self.evaluate_statement(node.value)
def evaluate_indexing(self, node: IndexNode) -> int: def evaluate_indexing(self, node: IndexNode) -> int:
return 0 return 0
@ -319,10 +319,10 @@ class AstInterpreter(InterpreterBase):
def assignment(self, node: AssignmentNode) -> None: def assignment(self, node: AssignmentNode) -> None:
assert isinstance(node, AssignmentNode) assert isinstance(node, AssignmentNode)
self.assignments[node.var_name] = node.value # Save a reference to the value node self.assignments[node.var_name.value] = node.value # Save a reference to the value node
if node.value.ast_id: if node.value.ast_id:
self.reverse_assignment[node.value.ast_id] = node self.reverse_assignment[node.value.ast_id] = node
self.assign_vals[node.var_name] = self.evaluate_statement(node.value) # Evaluate the value just in case self.assign_vals[node.var_name.value] = self.evaluate_statement(node.value) # Evaluate the value just in case
def resolve_node(self, node: BaseNode, include_unknown_args: bool = False, id_loop_detect: T.Optional[T.List[str]] = None) -> T.Optional[T.Any]: def resolve_node(self, node: BaseNode, include_unknown_args: bool = False, id_loop_detect: T.Optional[T.List[str]] = None) -> T.Optional[T.Any]:
def quick_resolve(n: BaseNode, loop_detect: T.Optional[T.List[str]] = None) -> T.Any: def quick_resolve(n: BaseNode, loop_detect: T.Optional[T.List[str]] = None) -> T.Any:
@ -382,17 +382,18 @@ class AstInterpreter(InterpreterBase):
src = quick_resolve(node.source_object) src = quick_resolve(node.source_object)
margs = self.flatten_args(node.args.arguments, include_unknown_args, id_loop_detect) margs = self.flatten_args(node.args.arguments, include_unknown_args, id_loop_detect)
mkwargs: T.Dict[str, TYPE_nvar] = {} mkwargs: T.Dict[str, TYPE_nvar] = {}
method_name = node.name.value
try: try:
if isinstance(src, str): if isinstance(src, str):
result = StringHolder(src, T.cast('Interpreter', self)).method_call(node.name, margs, mkwargs) result = StringHolder(src, T.cast('Interpreter', self)).method_call(method_name, margs, mkwargs)
elif isinstance(src, bool): elif isinstance(src, bool):
result = BooleanHolder(src, T.cast('Interpreter', self)).method_call(node.name, margs, mkwargs) result = BooleanHolder(src, T.cast('Interpreter', self)).method_call(method_name, margs, mkwargs)
elif isinstance(src, int): elif isinstance(src, int):
result = IntegerHolder(src, T.cast('Interpreter', self)).method_call(node.name, margs, mkwargs) result = IntegerHolder(src, T.cast('Interpreter', self)).method_call(method_name, margs, mkwargs)
elif isinstance(src, list): elif isinstance(src, list):
result = ArrayHolder(src, T.cast('Interpreter', self)).method_call(node.name, margs, mkwargs) result = ArrayHolder(src, T.cast('Interpreter', self)).method_call(method_name, margs, mkwargs)
elif isinstance(src, dict): elif isinstance(src, dict):
result = DictHolder(src, T.cast('Interpreter', self)).method_call(node.name, margs, mkwargs) result = DictHolder(src, T.cast('Interpreter', self)).method_call(method_name, margs, mkwargs)
except mesonlib.MesonException: except mesonlib.MesonException:
return None return None

@ -261,7 +261,7 @@ class IntrospectionInterpreter(AstInterpreter):
continue continue
arg_nodes = arg_node.arguments.copy() arg_nodes = arg_node.arguments.copy()
# Pop the first element if the function is a build target function # Pop the first element if the function is a build target function
if isinstance(curr, FunctionNode) and curr.func_name in BUILD_TARGET_FUNCTIONS: if isinstance(curr, FunctionNode) and curr.func_name.value in BUILD_TARGET_FUNCTIONS:
arg_nodes.pop(0) arg_nodes.pop(0)
elementary_nodes = [x for x in arg_nodes if isinstance(x, (str, BaseStringNode))] elementary_nodes = [x for x in arg_nodes if isinstance(x, (str, BaseStringNode))]
inqueue += [x for x in arg_nodes if isinstance(x, (FunctionNode, ArrayNode, IdNode, ArithmeticNode))] inqueue += [x for x in arg_nodes if isinstance(x, (FunctionNode, ArrayNode, IdNode, ArithmeticNode))]

@ -162,24 +162,24 @@ class AstPrinter(AstVisitor):
def visit_MethodNode(self, node: mparser.MethodNode) -> None: def visit_MethodNode(self, node: mparser.MethodNode) -> None:
node.lineno = self.curr_line or node.lineno node.lineno = self.curr_line or node.lineno
node.source_object.accept(self) node.source_object.accept(self)
self.append('.' + node.name + '(', node) self.append('.' + node.name.value + '(', node)
node.args.accept(self) node.args.accept(self)
self.append(')', node) self.append(')', node)
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None: def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
node.lineno = self.curr_line or node.lineno node.lineno = self.curr_line or node.lineno
self.append(node.func_name + '(', node) self.append(node.func_name.value + '(', node)
node.args.accept(self) node.args.accept(self)
self.append(')', node) self.append(')', node)
def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None: def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
node.lineno = self.curr_line or node.lineno node.lineno = self.curr_line or node.lineno
self.append(node.var_name + ' = ', node) self.append(node.var_name.value + ' = ', node)
node.value.accept(self) node.value.accept(self)
def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None: def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
node.lineno = self.curr_line or node.lineno node.lineno = self.curr_line or node.lineno
self.append(node.var_name + ' += ', node) self.append(node.var_name.value + ' += ', node)
node.value.accept(self) node.value.accept(self)
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None: def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
@ -352,22 +352,22 @@ class AstJSONPrinter(AstVisitor):
def visit_MethodNode(self, node: mparser.MethodNode) -> None: def visit_MethodNode(self, node: mparser.MethodNode) -> None:
self._accept('object', node.source_object) self._accept('object', node.source_object)
self._accept('args', node.args) self._accept('args', node.args)
self.current['name'] = node.name self.current['name'] = node.name.value
self.setbase(node) self.setbase(node)
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None: def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
self._accept('args', node.args) self._accept('args', node.args)
self.current['name'] = node.func_name self.current['name'] = node.func_name.value
self.setbase(node) self.setbase(node)
def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None: def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
self._accept('value', node.value) self._accept('value', node.value)
self.current['var_name'] = node.var_name self.current['var_name'] = node.var_name.value
self.setbase(node) self.setbase(node)
def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None: def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
self._accept('value', node.value) self._accept('value', node.value)
self.current['var_name'] = node.var_name self.current['var_name'] = node.var_name.value
self.setbase(node) self.setbase(node)
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None: def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:

@ -103,18 +103,22 @@ class AstVisitor:
def visit_MethodNode(self, node: mparser.MethodNode) -> None: def visit_MethodNode(self, node: mparser.MethodNode) -> None:
self.visit_default_func(node) self.visit_default_func(node)
node.source_object.accept(self) node.source_object.accept(self)
node.name.accept(self)
node.args.accept(self) node.args.accept(self)
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None: def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
self.visit_default_func(node) self.visit_default_func(node)
node.func_name.accept(self)
node.args.accept(self) node.args.accept(self)
def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None: def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
self.visit_default_func(node) self.visit_default_func(node)
node.var_name.accept(self)
node.value.accept(self) node.value.accept(self)
def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None: def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
self.visit_default_func(node) self.visit_default_func(node)
node.var_name.accept(self)
node.value.accept(self) node.value.accept(self)
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None: def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:

@ -97,7 +97,7 @@ def method(name: str, id_: mparser.IdNode,
args.arguments = pos args.arguments = pos
if kw is not None: if kw is not None:
args.kwargs = {identifier(k, id_.filename): v for k, v in kw.items()} args.kwargs = {identifier(k, id_.filename): v for k, v in kw.items()}
return mparser.MethodNode(id_.filename, -1, -1, id_, name, args) return mparser.MethodNode(id_.filename, -1, -1, id_, identifier(name, id_.filename), args)
def function(name: str, filename: str, def function(name: str, filename: str,
@ -117,7 +117,7 @@ def function(name: str, filename: str,
args.arguments = pos args.arguments = pos
if kw is not None: if kw is not None:
args.kwargs = {identifier(k, filename): v for k, v in kw.items()} args.kwargs = {identifier(k, filename): v for k, v in kw.items()}
return mparser.FunctionNode(filename, -1, -1, -1, -1, name, args) return mparser.FunctionNode(filename, -1, -1, -1, -1, identifier(name, filename), args)
def equal(lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.ComparisonNode: def equal(lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.ComparisonNode:
@ -168,7 +168,7 @@ def assign(value: mparser.BaseNode, varname: str, filename: str) -> mparser.Assi
:param filename: The filename :param filename: The filename
:return: An AssignmentNode :return: An AssignmentNode
""" """
return mparser.AssignmentNode(filename, -1, -1, varname, value) return mparser.AssignmentNode(filename, -1, -1, identifier(varname, filename), value)
def block(filename: str) -> mparser.CodeBlockNode: def block(filename: str) -> mparser.CodeBlockNode:

@ -1002,7 +1002,7 @@ class CMakeInterpreter:
args = [args] args = [args]
args_n.arguments = [nodeify(x) for x in args if x is not None] args_n.arguments = [nodeify(x) for x in args if x is not None]
args_n.kwargs = {id_node(k): nodeify(v) for k, v in kwargs.items() if v is not None} args_n.kwargs = {id_node(k): nodeify(v) for k, v in kwargs.items() if v is not None}
func_n = FunctionNode(self.subdir.as_posix(), 0, 0, 0, 0, name, args_n) func_n = FunctionNode(self.subdir.as_posix(), 0, 0, 0, 0, id_node(name), args_n)
return func_n return func_n
def method(obj: BaseNode, name: str, args: T.Optional[TYPE_mixed_list] = None, kwargs: T.Optional[TYPE_mixed_kwargs] = None) -> MethodNode: def method(obj: BaseNode, name: str, args: T.Optional[TYPE_mixed_list] = None, kwargs: T.Optional[TYPE_mixed_kwargs] = None) -> MethodNode:
@ -1014,10 +1014,10 @@ class CMakeInterpreter:
args = [args] args = [args]
args_n.arguments = [nodeify(x) for x in args if x is not None] args_n.arguments = [nodeify(x) for x in args if x is not None]
args_n.kwargs = {id_node(k): nodeify(v) for k, v in kwargs.items() if v is not None} args_n.kwargs = {id_node(k): nodeify(v) for k, v in kwargs.items() if v is not None}
return MethodNode(self.subdir.as_posix(), 0, 0, obj, name, args_n) return MethodNode(self.subdir.as_posix(), 0, 0, obj, id_node(name), args_n)
def assign(var_name: str, value: BaseNode) -> AssignmentNode: def assign(var_name: str, value: BaseNode) -> AssignmentNode:
return AssignmentNode(self.subdir.as_posix(), 0, 0, var_name, value) return AssignmentNode(self.subdir.as_posix(), 0, 0, id_node(var_name), value)
# Generate the root code block and the project function call # Generate the root code block and the project function call
root_cb = CodeBlockNode(token()) root_cb = CodeBlockNode(token())

@ -2942,7 +2942,7 @@ class Interpreter(InterpreterBase, HoldableObject):
def _add_global_arguments(self, node: mparser.FunctionNode, argsdict: T.Dict[str, T.List[str]], def _add_global_arguments(self, node: mparser.FunctionNode, argsdict: T.Dict[str, T.List[str]],
args: T.List[str], kwargs: 'kwtypes.FuncAddProjectArgs') -> None: args: T.List[str], kwargs: 'kwtypes.FuncAddProjectArgs') -> None:
if self.is_subproject(): if self.is_subproject():
msg = f'Function \'{node.func_name}\' cannot be used in subprojects because ' \ msg = f'Function \'{node.func_name.value}\' cannot be used in subprojects because ' \
'there is no way to make that reliable.\nPlease only call ' \ 'there is no way to make that reliable.\nPlease only call ' \
'this if is_subproject() returns false. Alternatively, ' \ 'this if is_subproject() returns false. Alternatively, ' \
'define a variable that\ncontains your language-specific ' \ 'define a variable that\ncontains your language-specific ' \
@ -2962,7 +2962,7 @@ class Interpreter(InterpreterBase, HoldableObject):
def _add_arguments(self, node: mparser.FunctionNode, argsdict: T.Dict[str, T.List[str]], def _add_arguments(self, node: mparser.FunctionNode, argsdict: T.Dict[str, T.List[str]],
args_frozen: bool, args: T.List[str], kwargs: 'kwtypes.FuncAddProjectArgs') -> None: args_frozen: bool, args: T.List[str], kwargs: 'kwtypes.FuncAddProjectArgs') -> None:
if args_frozen: if args_frozen:
msg = f'Tried to use \'{node.func_name}\' after a build target has been declared.\n' \ msg = f'Tried to use \'{node.func_name.value}\' after a build target has been declared.\n' \
'This is not permitted. Please declare all arguments before your targets.' 'This is not permitted. Please declare all arguments before your targets.'
raise InvalidCode(msg) raise InvalidCode(msg)

@ -137,7 +137,7 @@ class InterpreterBase:
if not self.ast.lines: if not self.ast.lines:
raise InvalidCode('No statements in code.') raise InvalidCode('No statements in code.')
first = self.ast.lines[0] first = self.ast.lines[0]
if not isinstance(first, mparser.FunctionNode) or first.func_name != 'project': if not isinstance(first, mparser.FunctionNode) or first.func_name.value != 'project':
p = pathlib.Path(self.source_root).resolve() p = pathlib.Path(self.source_root).resolve()
found = p found = p
for parent in p.parents: for parent in p.parents:
@ -476,7 +476,7 @@ class InterpreterBase:
def evaluate_plusassign(self, node: mparser.PlusAssignmentNode) -> None: def evaluate_plusassign(self, node: mparser.PlusAssignmentNode) -> None:
assert isinstance(node, mparser.PlusAssignmentNode) assert isinstance(node, mparser.PlusAssignmentNode)
varname = node.var_name varname = node.var_name.value
addition = self.evaluate_statement(node.value) addition = self.evaluate_statement(node.value)
if addition is None: if addition is None:
raise InvalidCodeOnVoid('plus assign') raise InvalidCodeOnVoid('plus assign')
@ -504,7 +504,7 @@ class InterpreterBase:
return self._holderify(iobject.operator_call(MesonOperator.INDEX, index)) return self._holderify(iobject.operator_call(MesonOperator.INDEX, index))
def function_call(self, node: mparser.FunctionNode) -> T.Optional[InterpreterObject]: def function_call(self, node: mparser.FunctionNode) -> T.Optional[InterpreterObject]:
func_name = node.func_name func_name = node.func_name.value
(h_posargs, h_kwargs) = self.reduce_arguments(node.args) (h_posargs, h_kwargs) = self.reduce_arguments(node.args)
(posargs, kwargs) = self._unholder_args(h_posargs, h_kwargs) (posargs, kwargs) = self._unholder_args(h_posargs, h_kwargs)
if is_disabled(posargs, kwargs) and func_name not in {'get_variable', 'set_variable', 'unset_variable', 'is_disabler'}: if is_disabled(posargs, kwargs) and func_name not in {'get_variable', 'set_variable', 'unset_variable', 'is_disabler'}:
@ -532,7 +532,7 @@ class InterpreterBase:
else: else:
object_display_name = invocable.__class__.__name__ object_display_name = invocable.__class__.__name__
obj = self.evaluate_statement(invocable) obj = self.evaluate_statement(invocable)
method_name = node.name method_name = node.name.value
(h_args, h_kwargs) = self.reduce_arguments(node.args) (h_args, h_kwargs) = self.reduce_arguments(node.args)
(args, kwargs) = self._unholder_args(h_args, h_kwargs) (args, kwargs) = self._unholder_args(h_args, h_kwargs)
if is_disabled(args, kwargs): if is_disabled(args, kwargs):
@ -628,7 +628,7 @@ class InterpreterBase:
Tried to assign values inside an argument list. Tried to assign values inside an argument list.
To specify a keyword argument, use : instead of =. To specify a keyword argument, use : instead of =.
''')) '''))
var_name = node.var_name var_name = node.var_name.value
if not isinstance(var_name, str): if not isinstance(var_name, str):
raise InvalidArguments('Tried to assign value to a non-variable.') raise InvalidArguments('Tried to assign value to a non-variable.')
value = self.evaluate_statement(node.value) value = self.evaluate_statement(node.value)

@ -187,7 +187,7 @@ def list_targets_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[st
args: T.List[BaseNode] = [] args: T.List[BaseNode] = []
if isinstance(n, FunctionNode): if isinstance(n, FunctionNode):
args = list(n.args.arguments) args = list(n.args.arguments)
if n.func_name in BUILD_TARGET_FUNCTIONS: if n.func_name.value in BUILD_TARGET_FUNCTIONS:
args.pop(0) args.pop(0)
elif isinstance(n, ArrayNode): elif isinstance(n, ArrayNode):
args = n.args.arguments args = n.args.arguments

@ -470,52 +470,48 @@ class IndexNode(BaseNode):
class MethodNode(BaseNode): class MethodNode(BaseNode):
source_object: BaseNode source_object: BaseNode
name: str name: IdNode
args: ArgumentNode args: ArgumentNode
def __init__(self, filename: str, lineno: int, colno: int, source_object: BaseNode, name: str, args: ArgumentNode): def __init__(self, filename: str, lineno: int, colno: int, source_object: BaseNode, name: IdNode, args: ArgumentNode):
super().__init__(lineno, colno, filename) super().__init__(lineno, colno, filename)
self.source_object = source_object self.source_object = source_object
self.name = name self.name = name
assert isinstance(self.name, str)
self.args = args self.args = args
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class FunctionNode(BaseNode): class FunctionNode(BaseNode):
func_name: str func_name: IdNode
args: ArgumentNode args: ArgumentNode
def __init__(self, filename: str, lineno: int, colno: int, end_lineno: int, end_colno: int, func_name: str, args: ArgumentNode): def __init__(self, filename: str, lineno: int, colno: int, end_lineno: int, end_colno: int, func_name: IdNode, args: ArgumentNode):
super().__init__(lineno, colno, filename, end_lineno=end_lineno, end_colno=end_colno) super().__init__(lineno, colno, filename, end_lineno=end_lineno, end_colno=end_colno)
self.func_name = func_name self.func_name = func_name
assert isinstance(func_name, str)
self.args = args self.args = args
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class AssignmentNode(BaseNode): class AssignmentNode(BaseNode):
var_name: str var_name: IdNode
value: BaseNode value: BaseNode
def __init__(self, filename: str, lineno: int, colno: int, var_name: str, value: BaseNode): def __init__(self, filename: str, lineno: int, colno: int, var_name: IdNode, value: BaseNode):
super().__init__(lineno, colno, filename) super().__init__(lineno, colno, filename)
self.var_name = var_name self.var_name = var_name
assert isinstance(var_name, str)
self.value = value self.value = value
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class PlusAssignmentNode(BaseNode): class PlusAssignmentNode(BaseNode):
var_name: str var_name: IdNode
value: BaseNode value: BaseNode
def __init__(self, filename: str, lineno: int, colno: int, var_name: str, value: BaseNode): def __init__(self, filename: str, lineno: int, colno: int, var_name: IdNode, value: BaseNode):
super().__init__(lineno, colno, filename) super().__init__(lineno, colno, filename)
self.var_name = var_name self.var_name = var_name
assert isinstance(var_name, str)
self.value = value self.value = value
@ -687,14 +683,14 @@ class Parser:
if not isinstance(left, IdNode): if not isinstance(left, IdNode):
raise ParseException('Plusassignment target must be an id.', self.getline(), left.lineno, left.colno) raise ParseException('Plusassignment target must be an id.', self.getline(), left.lineno, left.colno)
assert isinstance(left.value, str) assert isinstance(left.value, str)
return PlusAssignmentNode(left.filename, left.lineno, left.colno, left.value, value) return PlusAssignmentNode(left.filename, left.lineno, left.colno, left, value)
elif self.accept('assign'): elif self.accept('assign'):
value = self.e1() value = self.e1()
if not isinstance(left, IdNode): if not isinstance(left, IdNode):
raise ParseException('Assignment target must be an id.', raise ParseException('Assignment target must be an id.',
self.getline(), left.lineno, left.colno) self.getline(), left.lineno, left.colno)
assert isinstance(left.value, str) assert isinstance(left.value, str)
return AssignmentNode(left.filename, left.lineno, left.colno, left.value, value) return AssignmentNode(left.filename, left.lineno, left.colno, left, value)
elif self.accept('questionmark'): elif self.accept('questionmark'):
if self.in_ternary: if self.in_ternary:
raise ParseException('Nested ternary operators are not allowed.', raise ParseException('Nested ternary operators are not allowed.',
@ -783,7 +779,7 @@ class Parser:
raise ParseException('Function call must be applied to plain id', raise ParseException('Function call must be applied to plain id',
self.getline(), left.lineno, left.colno) self.getline(), left.lineno, left.colno)
assert isinstance(left.value, str) assert isinstance(left.value, str)
left = FunctionNode(left.filename, left.lineno, left.colno, self.current.lineno, self.current.colno, left.value, args) left = FunctionNode(left.filename, left.lineno, left.colno, self.current.lineno, self.current.colno, left, args)
go_again = True go_again = True
while go_again: while go_again:
go_again = False go_again = False
@ -887,7 +883,7 @@ class Parser:
self.expect('lparen') self.expect('lparen')
args = self.args() args = self.args()
self.expect('rparen') self.expect('rparen')
method = MethodNode(methodname.filename, methodname.lineno, methodname.colno, source_object, methodname.value, args) method = MethodNode(methodname.filename, methodname.lineno, methodname.colno, source_object, methodname, args)
if self.accept('dot'): if self.accept('dot'):
return self.method_call(method) return self.method_call(method)
return method return method

@ -164,7 +164,7 @@ class OptionInterpreter:
def evaluate_statement(self, node: mparser.BaseNode) -> None: def evaluate_statement(self, node: mparser.BaseNode) -> None:
if not isinstance(node, mparser.FunctionNode): if not isinstance(node, mparser.FunctionNode):
raise OptionException('Option file may only contain option definitions') raise OptionException('Option file may only contain option definitions')
func_name = node.func_name func_name = node.func_name.value
if func_name != 'option': if func_name != 'option':
raise OptionException('Only calls to option() are allowed in option files.') raise OptionException('Only calls to option() are allowed in option files.')
(posargs, kwargs) = self.reduce_arguments(node.args) (posargs, kwargs) = self.reduce_arguments(node.args)

@ -420,7 +420,7 @@ class Rewriter:
if target in self.interpreter.assignments: if target in self.interpreter.assignments:
node = self.interpreter.assignments[target] node = self.interpreter.assignments[target]
if isinstance(node, FunctionNode): if isinstance(node, FunctionNode):
if node.func_name in {'executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library', 'both_libraries'}: if node.func_name.value in {'executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library', 'both_libraries'}:
tgt = self.interpreter.assign_vals[target] tgt = self.interpreter.assign_vals[target]
return tgt return tgt
@ -440,7 +440,7 @@ class Rewriter:
if dependency in self.interpreter.assignments: if dependency in self.interpreter.assignments:
node = self.interpreter.assignments[dependency] node = self.interpreter.assignments[dependency]
if isinstance(node, FunctionNode): if isinstance(node, FunctionNode):
if node.func_name == 'dependency': if node.func_name.value == 'dependency':
name = self.interpreter.flatten_args(node.args)[0] name = self.interpreter.flatten_args(node.args)[0]
dep = check_list(name) dep = check_list(name)
@ -630,7 +630,7 @@ class Rewriter:
args = [] args = []
if isinstance(n, FunctionNode): if isinstance(n, FunctionNode):
args = list(n.args.arguments) args = list(n.args.arguments)
if n.func_name in BUILD_TARGET_FUNCTIONS: if n.func_name.value in BUILD_TARGET_FUNCTIONS:
args.pop(0) args.pop(0)
elif isinstance(n, ArrayNode): elif isinstance(n, ArrayNode):
args = n.args.arguments args = n.args.arguments
@ -814,15 +814,15 @@ class Rewriter:
src_arg_node = ArgumentNode(Token('string', filename, 0, 0, 0, None, '')) src_arg_node = ArgumentNode(Token('string', filename, 0, 0, 0, None, ''))
src_arr_node = ArrayNode(src_arg_node, 0, 0, 0, 0) src_arr_node = ArrayNode(src_arg_node, 0, 0, 0, 0)
src_far_node = ArgumentNode(Token('string', filename, 0, 0, 0, None, '')) src_far_node = ArgumentNode(Token('string', filename, 0, 0, 0, None, ''))
src_fun_node = FunctionNode(filename, 0, 0, 0, 0, 'files', src_far_node) src_fun_node = FunctionNode(filename, 0, 0, 0, 0, IdNode(Token('id', filename, 0, 0, 0, (0, 0), 'files')), src_far_node)
src_ass_node = AssignmentNode(filename, 0, 0, source_id, src_fun_node) src_ass_node = AssignmentNode(filename, 0, 0, IdNode(Token('id', filename, 0, 0, 0, (0, 0), source_id)), src_fun_node)
src_arg_node.arguments = [StringNode(Token('string', filename, 0, 0, 0, None, x)) for x in cmd['sources']] src_arg_node.arguments = [StringNode(Token('string', filename, 0, 0, 0, None, x)) for x in cmd['sources']]
src_far_node.arguments = [src_arr_node] src_far_node.arguments = [src_arr_node]
# Build target # Build target
tgt_arg_node = ArgumentNode(Token('string', filename, 0, 0, 0, None, '')) tgt_arg_node = ArgumentNode(Token('string', filename, 0, 0, 0, None, ''))
tgt_fun_node = FunctionNode(filename, 0, 0, 0, 0, cmd['target_type'], tgt_arg_node) tgt_fun_node = FunctionNode(filename, 0, 0, 0, 0, IdNode(Token('id', filename, 0, 0, 0, (0, 0), cmd['target_type'])), tgt_arg_node)
tgt_ass_node = AssignmentNode(filename, 0, 0, target_id, tgt_fun_node) tgt_ass_node = AssignmentNode(filename, 0, 0, IdNode(Token('id', filename, 0, 0, 0, (0, 0), target_id)), tgt_fun_node)
tgt_arg_node.arguments = [ tgt_arg_node.arguments = [
StringNode(Token('string', filename, 0, 0, 0, None, cmd['target'])), StringNode(Token('string', filename, 0, 0, 0, None, cmd['target'])),
IdNode(Token('string', filename, 0, 0, 0, None, source_id)) IdNode(Token('string', filename, 0, 0, 0, None, source_id))

Loading…
Cancel
Save