aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2022-02-24 13:26:51 -0800
committerDylan Baker <dylan@pnwbakers.com>2023-06-07 19:20:30 -0700
commitb01ae087f5f54b0777201c83440fb6777648acd8 (patch)
tree4d1a3e6b9c0b83c28a7233d5d0eb5bcbce0e11b1
parent71325547aa26094ca456a679bdfed919220e96df (diff)
downloadmeson-b01ae087f5f54b0777201c83440fb6777648acd8.zip
meson-b01ae087f5f54b0777201c83440fb6777648acd8.tar.gz
meson-b01ae087f5f54b0777201c83440fb6777648acd8.tar.bz2
cargo: Add a builder module to the cargo package
This is a helper, currently only used by cargo. It could be moved later if there are other users.
-rw-r--r--mesonbuild/cargo/__init__.py0
-rw-r--r--mesonbuild/cargo/builder.py284
-rwxr-xr-xrun_mypy.py1
3 files changed, 285 insertions, 0 deletions
diff --git a/mesonbuild/cargo/__init__.py b/mesonbuild/cargo/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mesonbuild/cargo/__init__.py
diff --git a/mesonbuild/cargo/builder.py b/mesonbuild/cargo/builder.py
new file mode 100644
index 0000000..49bc65d
--- /dev/null
+++ b/mesonbuild/cargo/builder.py
@@ -0,0 +1,284 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright © 2022-2023 Intel Corporation
+
+"""Provides helpers for building AST
+
+This is meant to make building Meson AST from foreign (largely declarative)
+build descriptions easier.
+"""
+
+from __future__ import annotations
+import builtins
+import dataclasses
+import typing as T
+
+from .. import mparser
+
+
+def _token(tid: str, filename: str, value: mparser.TV_TokenTypes) -> mparser.Token[mparser.TV_TokenTypes]:
+ """Create a Token object, but with the line numbers stubbed out.
+
+ :param tid: the token id (such as string, number, etc)
+ :param filename: the filename that the token was generated from
+ :param value: the value of the token
+ :return: A Token object
+ """
+ return mparser.Token(tid, filename, -1, -1, -1, (-1, -1), value)
+
+
+def string(value: str, filename: str) -> mparser.StringNode:
+ """Build A StringNode
+
+ :param value: the value of the string
+ :param filename: the file that the value came from
+ :return: A StringNode
+ """
+ return mparser.StringNode(_token('string', filename, value))
+
+
+def number(value: int, filename: str) -> mparser.NumberNode:
+ """Build A NumberNode
+
+ :param value: the value of the number
+ :param filename: the file that the value came from
+ :return: A NumberNode
+ """
+ return mparser.NumberNode(_token('number', filename, value))
+
+
+def bool(value: builtins.bool, filename: str) -> mparser.BooleanNode:
+ """Build A BooleanNode
+
+ :param value: the value of the boolean
+ :param filename: the file that the value came from
+ :return: A BooleanNode
+ """
+ return mparser.BooleanNode(_token('bool', filename, value))
+
+
+def array(value: T.List[mparser.BaseNode], filename: str) -> mparser.ArrayNode:
+ """Build an Array Node
+
+ :param value: A list of nodes to insert into the array
+ :param filename: The file the array is from
+ :return: An ArrayNode built from the arguments
+ """
+ args = mparser.ArgumentNode(_token('array', filename, 'unused'))
+ args.arguments = value
+ return mparser.ArrayNode(args, -1, -1, -1, -1)
+
+
+def identifier(value: str, filename: str) -> mparser.IdNode:
+ """Build A IdNode
+
+ :param value: the value of the boolean
+ :param filename: the file that the value came from
+ :return: A BooleanNode
+ """
+ return mparser.IdNode(_token('id', filename, value))
+
+
+def method(name: str, id_: mparser.IdNode,
+ pos: T.Optional[T.List[mparser.BaseNode]] = None,
+ kw: T.Optional[T.Mapping[str, mparser.BaseNode]] = None,
+ ) -> mparser.MethodNode:
+ """Create a method call.
+
+ :param name: the name of the method
+ :param id_: the object to call the method of
+ :param pos: a list of positional arguments, defaults to None
+ :param kw: a dictionary of keyword arguments, defaults to None
+ :return: a method call object
+ """
+ args = mparser.ArgumentNode(_token('array', id_.filename, 'unused'))
+ if pos is not None:
+ args.arguments = pos
+ if kw is not None:
+ args.kwargs = {identifier(k, id_.filename): v for k, v in kw.items()}
+ return mparser.MethodNode(id_.filename, -1, -1, id_, name, args)
+
+
+def function(name: str, filename: str,
+ pos: T.Optional[T.List[mparser.BaseNode]] = None,
+ kw: T.Optional[T.Mapping[str, mparser.BaseNode]] = None,
+ ) -> mparser.FunctionNode:
+ """Create a function call.
+
+ :param name: the name of the function
+ :param filename: The name of the current file being evaluated
+ :param pos: a list of positional arguments, defaults to None
+ :param kw: a dictionary of keyword arguments, defaults to None
+ :return: a method call object
+ """
+ args = mparser.ArgumentNode(_token('array', filename, 'unused'))
+ if pos is not None:
+ args.arguments = pos
+ if kw is not None:
+ args.kwargs = {identifier(k, filename): v for k, v in kw.items()}
+ return mparser.FunctionNode(filename, -1, -1, -1, -1, name, args)
+
+
+def equal(lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.ComparisonNode:
+ """Create an equality operation
+
+ :param lhs: The left hand side of the equal
+ :param rhs: the right hand side of the equal
+ :return: A compraison node
+ """
+ return mparser.ComparisonNode('==', lhs, rhs)
+
+
+def or_(lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.OrNode:
+ """Create and OrNode
+
+ :param lhs: The Left of the Node
+ :param rhs: The Right of the Node
+ :return: The OrNode
+ """
+ return mparser.OrNode(lhs, rhs)
+
+
+def and_(lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.AndNode:
+ """Create an AndNode
+
+ :param lhs: The left of the And
+ :param rhs: The right of the And
+ :return: The AndNode
+ """
+ return mparser.AndNode(lhs, rhs)
+
+
+def not_(value: mparser.BaseNode, filename: str) -> mparser.NotNode:
+ """Create a not node
+
+ :param value: The value to negate
+ :param filename: the string filename
+ :return: The NotNode
+ """
+ return mparser.NotNode(_token('not', filename, ''), value)
+
+
+def assign(value: mparser.BaseNode, varname: str, filename: str) -> mparser.AssignmentNode:
+ """Create an AssignmentNode
+
+ :param value: The rvalue
+ :param varname: The lvalue
+ :param filename: The filename
+ :return: An AssignmentNode
+ """
+ return mparser.AssignmentNode(filename, -1, -1, varname, value)
+
+
+def block(filename: str) -> mparser.CodeBlockNode:
+ return mparser.CodeBlockNode(_token('node', filename, ''))
+
+
+@dataclasses.dataclass
+class Builder:
+
+ filename: str
+
+ def assign(self, value: mparser.BaseNode, varname: str) -> mparser.AssignmentNode:
+ return assign(value, varname, self.filename)
+
+ def string(self, value: str) -> mparser.StringNode:
+ """Build A StringNode
+
+ :param value: the value of the string
+ :return: A StringNode
+ """
+ return string(value, self.filename)
+
+ def number(self, value: int) -> mparser.NumberNode:
+ """Build A NumberNode
+
+ :param value: the value of the number
+ :return: A NumberNode
+ """
+ return number(value, self.filename)
+
+ def bool(self, value: builtins.bool) -> mparser.BooleanNode:
+ """Build A BooleanNode
+
+ :param value: the value of the boolean
+ :return: A BooleanNode
+ """
+ return bool(value, self.filename)
+
+ def array(self, value: T.List[mparser.BaseNode]) -> mparser.ArrayNode:
+ """Build an Array Node
+
+ :param value: A list of nodes to insert into the array
+ :return: An ArrayNode built from the arguments
+ """
+ return array(value, self.filename)
+
+ def identifier(self, value: str) -> mparser.IdNode:
+ """Build A IdNode
+
+ :param value: the value of the boolean
+ :return: A BooleanNode
+ """
+ return identifier(value, self.filename)
+
+ def method(self, name: str, id_: mparser.IdNode,
+ pos: T.Optional[T.List[mparser.BaseNode]] = None,
+ kw: T.Optional[T.Mapping[str, mparser.BaseNode]] = None,
+ ) -> mparser.MethodNode:
+ """Create a method call.
+
+ :param name: the name of the method
+ :param id_: the object to call the method of
+ :param pos: a list of positional arguments, defaults to None
+ :param kw: a dictionary of keyword arguments, defaults to None
+ :return: a method call object
+ """
+ return method(name, id_, pos or [], kw or {})
+
+ def function(self, name: str,
+ pos: T.Optional[T.List[mparser.BaseNode]] = None,
+ kw: T.Optional[T.Mapping[str, mparser.BaseNode]] = None,
+ ) -> mparser.FunctionNode:
+ """Create a function call.
+
+ :param name: the name of the function
+ :param pos: a list of positional arguments, defaults to None
+ :param kw: a dictionary of keyword arguments, defaults to None
+ :return: a method call object
+ """
+ return function(name, self.filename, pos or [], kw or {})
+
+ def equal(self, lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.ComparisonNode:
+ """Create an equality operation
+
+ :param lhs: The left hand side of the equal
+ :param rhs: the right hand side of the equal
+ :return: A compraison node
+ """
+ return equal(lhs, rhs)
+
+ def or_(self, lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.OrNode:
+ """Create and OrNode
+
+ :param lhs: The Left of the Node
+ :param rhs: The Right of the Node
+ :return: The OrNode
+ """
+ return or_(lhs, rhs)
+
+ def and_(self, lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.AndNode:
+ """Create an AndNode
+
+ :param lhs: The left of the And
+ :param rhs: The right of the And
+ :return: The AndNode
+ """
+ return and_(lhs, rhs)
+
+ def not_(self, value: mparser.BaseNode, filename: str) -> mparser.NotNode:
+ """Create a not node
+
+ :param value: The value to negate
+ :return: The NotNode
+ """
+ return not_(value, self.filename)
diff --git a/run_mypy.py b/run_mypy.py
index 338968d..158f765 100755
--- a/run_mypy.py
+++ b/run_mypy.py
@@ -12,6 +12,7 @@ from mesonbuild.mesonlib import version_compare
modules = [
# fully typed submodules
# 'mesonbuild/ast/',
+ 'mesonbuild/cargo/',
'mesonbuild/cmake/',
'mesonbuild/compilers/',
'mesonbuild/dependencies/',