pyVHDLModelTreesitter 0.7.1__tar.gz → 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/PKG-INFO +17 -17
  2. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/pyproject.toml +21 -23
  3. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/Expression.py +37 -0
  4. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Association.py +53 -0
  5. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Base.py +154 -0
  6. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Concurrent.py +192 -0
  7. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Design.py +24 -0
  8. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_DesignUnit.py +393 -0
  9. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Document.py +158 -0
  10. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Interface.py +138 -0
  11. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Name.py +20 -0
  12. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_Object.py +83 -0
  13. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/__init__.py +1 -12
  14. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/_errors.py +5 -0
  15. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/_parse.py +195 -123
  16. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/_subtype_indication.py +169 -0
  17. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/format.py +375 -0
  18. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/__init__.py +8 -4
  19. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/_protocol.py +62 -0
  20. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/_utils.py +0 -17
  21. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/bit_string_literal.scm +5 -0
  22. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/component_declaration.scm +8 -0
  23. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/concurrent_conditional_signal_assignment.scm +6 -0
  24. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/constant_declaration.scm +13 -0
  25. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/constrained_scalar.scm +17 -0
  26. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/physical_literal.scm +4 -0
  27. pyvhdlmodeltreesitter-0.8.0/src/pyVHDLModelTreesitter/treesitter/queries/signal_declaration.scm +13 -0
  28. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/query.py +21 -1
  29. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Association.py +0 -104
  30. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Base.py +0 -205
  31. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Concurrent.py +0 -244
  32. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/DesignUnit.py +0 -497
  33. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Expression.py +0 -651
  34. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Interface.py +0 -213
  35. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Name.py +0 -117
  36. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Object.py +0 -146
  37. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/Symbol.py +0 -200
  38. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/_Design.py +0 -55
  39. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/_Document.py +0 -166
  40. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/_Library.py +0 -46
  41. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/cli/__init__.py +0 -1
  42. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/cli/_dump_treesitter_parse.py +0 -29
  43. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/format.py +0 -68
  44. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/treesitter/_base_class.py +0 -30
  45. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/treesitter/queries/constant_declaration.scm +0 -10
  46. pyvhdlmodeltreesitter-0.7.1/src/pyVHDLModelTreesitter/treesitter/queries/signal_declaration.scm +0 -10
  47. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/.gitignore +0 -0
  48. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/LICENSE +0 -0
  49. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/README.md +0 -0
  50. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/py.typed +0 -0
  51. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/adding_expression.scm +0 -0
  52. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/architecture_definition.scm +0 -0
  53. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/association_element.scm +0 -0
  54. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/association_elements.scm +0 -0
  55. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/association_list_simple_range.scm +0 -0
  56. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/component_instantiation_statement.scm +0 -0
  57. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/concurrent_simple_signal_assignment.scm +0 -0
  58. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/constrained_1d_array.scm +0 -0
  59. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/design_units.scm +0 -0
  60. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/entity_declaration.scm +0 -0
  61. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/function_call.scm +0 -0
  62. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/ignorable_parentheses.scm +0 -0
  63. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/indexed_name.scm +0 -0
  64. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/interface_declaration.scm +0 -0
  65. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/interface_declarations.scm +0 -0
  66. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/library_clauses.scm +0 -0
  67. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/library_namespaces.scm +0 -0
  68. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/logical_expression.scm +0 -0
  69. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/multiplying_expression.scm +0 -0
  70. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/package_declaration.scm +0 -0
  71. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/package_definition.scm +0 -0
  72. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/relational_expression.scm +0 -0
  73. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/selected_names.scm +0 -0
  74. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/shift_expression.scm +0 -0
  75. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/simple_subtype.scm +0 -0
  76. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/type_conversion.scm +0 -0
  77. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/unary_expression.scm +0 -0
  78. {pyvhdlmodeltreesitter-0.7.1 → pyvhdlmodeltreesitter-0.8.0}/src/pyVHDLModelTreesitter/treesitter/queries/use_clauses.scm +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyVHDLModelTreesitter
3
- Version: 0.7.1
3
+ Version: 0.8.0
4
4
  Summary: An implementation of pyVHDLModel using treesitter
5
5
  Project-URL: Repository, https://gitlab.com/dawalters/pyVHDLModelTreesitter
6
6
  Author: Dominic Adam Walters
@@ -16,26 +16,26 @@ Classifier: Programming Language :: Python :: 3.13
16
16
  Classifier: Programming Language :: Python :: 3.14
17
17
  Requires-Python: >=3.11
18
18
  Requires-Dist: pygments>=2.20.0
19
- Requires-Dist: pyvhdlmodel>=0.34.0
19
+ Requires-Dist: pyvhdlmodel>=0.38.0
20
20
  Requires-Dist: rich>=11.0.0
21
21
  Requires-Dist: tree-sitter-vhdl>=1.2.5
22
22
  Requires-Dist: tree-sitter>=0.23.0
23
23
  Provides-Extra: dev
24
- Requires-Dist: coverage==7.15.0; extra == 'dev'
25
- Requires-Dist: cryptography==49.0.0; extra == 'dev'
26
- Requires-Dist: hatch==1.17.0; extra == 'dev'
27
- Requires-Dist: idna==3.18; extra == 'dev'
28
- Requires-Dist: jaraco-context==6.1.2; extra == 'dev'
29
- Requires-Dist: mypy==2.1.0; extra == 'dev'
30
- Requires-Dist: pre-commit==4.6.0; extra == 'dev'
31
- Requires-Dist: pytest-cov==7.1.0; extra == 'dev'
32
- Requires-Dist: pytest-order==1.5.0; extra == 'dev'
33
- Requires-Dist: pytest-sugar==1.1.1; extra == 'dev'
34
- Requires-Dist: pytest-xdist==3.8.0; extra == 'dev'
35
- Requires-Dist: pytest==9.1.1; extra == 'dev'
36
- Requires-Dist: ruff==0.15.20; extra == 'dev'
37
- Requires-Dist: ty==0.0.56; extra == 'dev'
38
- Requires-Dist: uv==0.11.26; extra == 'dev'
24
+ Requires-Dist: coverage>=7.15.2; extra == 'dev'
25
+ Requires-Dist: cryptography>=49.0.0; extra == 'dev'
26
+ Requires-Dist: hatch>=1.17.1; extra == 'dev'
27
+ Requires-Dist: idna>=3.18; extra == 'dev'
28
+ Requires-Dist: jaraco-context>=6.1.2; extra == 'dev'
29
+ Requires-Dist: mypy>=2.3.0; extra == 'dev'
30
+ Requires-Dist: pre-commit>=4.6.1; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
32
+ Requires-Dist: pytest-order>=1.5.0; extra == 'dev'
33
+ Requires-Dist: pytest-sugar>=1.1.1; extra == 'dev'
34
+ Requires-Dist: pytest-xdist>=3.8.0; extra == 'dev'
35
+ Requires-Dist: pytest>=9.1.1; extra == 'dev'
36
+ Requires-Dist: ruff>=0.16.1; extra == 'dev'
37
+ Requires-Dist: ty>=0.0.65; extra == 'dev'
38
+ Requires-Dist: uv>=0.12.0; extra == 'dev'
39
39
  Description-Content-Type: text/markdown
40
40
 
41
41
  # pyVHDLModelTreesitter
@@ -4,16 +4,16 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pyVHDLModelTreesitter"
7
- version = "0.7.1"
7
+ version = "0.8.0"
8
8
  description = "An implementation of pyVHDLModel using treesitter"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  dependencies = [
12
- "pyVHDLModel >= 0.34.0",
12
+ "pyVHDLModel >= 0.38.0",
13
13
  "rich >= 11.0.0",
14
14
  "pygments >= 2.20.0", # forced to avoid CVE
15
15
  "tree-sitter >= 0.23.0",
16
- "tree-sitter-vhdl >= 1.2.5",
16
+ "tree-sitter-vhdl >= 1.2.5", # TODO: move to 1.6.0 once released
17
17
  ]
18
18
  authors = [
19
19
  { name = "Dominic Adam Walters" },
@@ -32,26 +32,23 @@ classifiers = [
32
32
 
33
33
  [project.optional-dependencies]
34
34
  dev = [
35
- "coverage == 7.15.0",
36
- "hatch == 1.17.0",
37
- "cryptography == 49.0.0", # forced to avoid CVE
38
- "idna == 3.18", # forced to avoid CVE
39
- "jaraco-context == 6.1.2", # forced to avoid CVE
40
- "mypy == 2.1.0",
41
- "pre-commit == 4.6.0",
42
- "pytest == 9.1.1",
43
- "pytest-cov == 7.1.0",
44
- "pytest-order == 1.5.0",
45
- "pytest-sugar == 1.1.1",
46
- "pytest-xdist == 3.8.0",
47
- "ruff == 0.15.20",
48
- "ty == 0.0.56",
49
- "uv == 0.11.26",
35
+ "coverage >= 7.15.2",
36
+ "hatch >= 1.17.1",
37
+ "cryptography >= 49.0.0", # forced to avoid CVE
38
+ "idna >= 3.18", # forced to avoid CVE
39
+ "jaraco-context >= 6.1.2", # forced to avoid CVE
40
+ "mypy >= 2.3.0",
41
+ "pre-commit >= 4.6.1",
42
+ "pytest >= 9.1.1",
43
+ "pytest-cov >= 7.1.0",
44
+ "pytest-order >= 1.5.0",
45
+ "pytest-sugar >= 1.1.1",
46
+ "pytest-xdist >= 3.8.0",
47
+ "ruff >= 0.16.1",
48
+ "ty >= 0.0.65",
49
+ "uv >= 0.12.0",
50
50
  ]
51
51
 
52
- [project.scripts]
53
- dump-treesitter-parse = "pyVHDLModelTreesitter.cli._dump_treesitter_parse:main"
54
-
55
52
  [project.urls]
56
53
  Repository = "https://gitlab.com/dawalters/pyVHDLModelTreesitter"
57
54
 
@@ -92,12 +89,13 @@ dependencies = [
92
89
  python = ["3.11", "3.12", "3.13", "3.14"]
93
90
 
94
91
  [tool.mypy]
92
+ implicit_reexport = true
93
+ scripts_are_modules = true
95
94
  strict = true
96
95
  warn_unreachable = true
97
- implicit_reexport = true
98
96
 
99
97
  [tool.pytest.ini_options]
100
- addopts = "--capture=fd -n 0 --cov=pyVHDLModelTreesitter --cov-report html --cov-report xml --verbose --junitxml=.junit.xml -o junit_family=legacy"
98
+ addopts = "--capture=fd -n auto --dist loadgroup --cov=pyVHDLModelTreesitter --cov-report html --cov-report xml --verbose --junitxml=.junit.xml -o junit_family=legacy"
101
99
  norecursedirs = "oss/*"
102
100
  testpaths = [
103
101
  "tests",
@@ -0,0 +1,37 @@
1
+ """Submodule mirroring modified aspects of pyVHDLModel.Expression."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "FunctionCall",
7
+ ]
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+ import pyVHDLModel
12
+
13
+ if TYPE_CHECKING:
14
+ from pyVHDLModel.Association import ParameterAssociationItem
15
+ from pyVHDLModel.Name import Name
16
+
17
+
18
+ #####################################
19
+ # Modified first order base classes #
20
+ #####################################
21
+ class FunctionCall(pyVHDLModel.Expression.FunctionCall): # ruff: ignore[undocumented-public-class]
22
+ # TODO: Report on pyVHDLModel that function calls are currently undefined
23
+ _name: Name
24
+ _arguments: list[ParameterAssociationItem]
25
+
26
+ def __init__( # ruff: ignore[undocumented-public-init]
27
+ self,
28
+ name: Name,
29
+ arguments: list[ParameterAssociationItem],
30
+ parent: pyVHDLModel.Base.ModelEntity | None = None,
31
+ ) -> None:
32
+ super().__init__(parent)
33
+ self._name = name
34
+ self._arguments = arguments
35
+
36
+ def __str__(self) -> str: # ruff: ignore[undocumented-magic-method]
37
+ return f"{self._name}({', '.join(str(a) for a in self._arguments)})"
@@ -0,0 +1,53 @@
1
+ """Submodule defining parsers for classes from pyVHDLModel.Association."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "parse_association_item",
7
+ ]
8
+
9
+ from typing import TYPE_CHECKING, TypeVar
10
+
11
+ from pyVHDLModel.Association import AssociationItem
12
+ from pyVHDLModel.Name import OpenName
13
+ from pyVHDLModel.Symbol import SignalSymbol
14
+
15
+ from pyVHDLModelTreesitter._Name import parse_name
16
+ from pyVHDLModelTreesitter.treesitter import (
17
+ get_node,
18
+ get_node_text,
19
+ inject_node,
20
+ )
21
+ from pyVHDLModelTreesitter.treesitter.query import AssociationElement
22
+
23
+ if TYPE_CHECKING:
24
+ import pyVHDLModel
25
+ import tree_sitter
26
+
27
+
28
+ T = TypeVar("T", bound=AssociationItem)
29
+
30
+
31
+ def parse_association_item(cls: type[T], node: tree_sitter.Node) -> T | None:
32
+ """Create an AssociationItem from a tree-sitter node."""
33
+ captures = AssociationElement.capture_first_root(node)
34
+ formal_node = get_node(node, captures, "formal", optional=True)
35
+ formal = None
36
+ if formal_node is not None:
37
+ formal = SignalSymbol(parse_name(get_node_text(formal_node)))
38
+ actual_node = get_node(node, captures, "actual")
39
+ actual: pyVHDLModel.Base.ExpressionUnion
40
+ if actual_node.type == "OPEN":
41
+ actual = OpenName()
42
+ else:
43
+ # ruff: ignore[import-outside-top-level]
44
+ from pyVHDLModelTreesitter._parse import parse_conditional_expression
45
+
46
+ actual = parse_conditional_expression(actual_node)
47
+ if actual is None:
48
+ return None
49
+ # TODO: `formal` is a `SignalSymbol`, is this correct?
50
+ # TODO: `OpenName` might need wrapping in a `Symbol`
51
+ # ty: ignore[invalid-argument-type]
52
+ ret = cls(formal, actual) # type: ignore[arg-type]
53
+ return inject_node(ret, node)
@@ -0,0 +1,154 @@
1
+ """Submodule defining parsers for classes from pyVHDLModel.Base."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "parse_direction",
7
+ "parse_mode",
8
+ "parse_simple_range",
9
+ "parse_waveform_element",
10
+ ]
11
+
12
+ from typing import TYPE_CHECKING
13
+
14
+ import pyVHDLModel
15
+ from pyVHDLModel.Base import SimpleRange, WaveformElement
16
+
17
+ if TYPE_CHECKING:
18
+ from tree_sitter import Node
19
+
20
+ from pyVHDLModelTreesitter._errors import (
21
+ NodeExtraChildError,
22
+ NodeMissingChildError,
23
+ NodeTextIsInvalidError,
24
+ NodeTextIsNoneError,
25
+ NotImplementedWarning,
26
+ )
27
+ from pyVHDLModelTreesitter._parse import parse_simple_expression
28
+ from pyVHDLModelTreesitter.treesitter import inject_node
29
+
30
+
31
+ def parse_direction(string: str) -> pyVHDLModel.Base.Direction | None:
32
+ """
33
+ Parse a string as a direction.
34
+
35
+ This will accept any mix of the following:
36
+ - Incorrect capitalisation
37
+ - "tO"
38
+ - "To"
39
+ - Split words with whitespace
40
+ - "down to"
41
+ """
42
+ # TODO: make a PR on pyVHDLModel to add this
43
+ string = "".join(string.split()).lower().capitalize()
44
+ if string == "Downto":
45
+ string = "DownTo"
46
+ try:
47
+ return pyVHDLModel.Base.Direction[string]
48
+ except IndexError:
49
+ return None
50
+
51
+
52
+ def parse_mode(string: str) -> pyVHDLModel.Base.Mode | None:
53
+ """
54
+ Parse a string as a mode.
55
+
56
+ This will accept any mix of the following:
57
+ - Incorrect capitalisation
58
+ - "IN"
59
+ - "iN"
60
+ - "in"
61
+ - Split words with whitespace
62
+ - "in out"
63
+ """
64
+ # TODO: make a PR on pyVHDLModel to add this
65
+ string = "".join(string.split()).lower().capitalize()
66
+ if string == "Inout":
67
+ string = "InOut"
68
+ try:
69
+ return pyVHDLModel.Base.Mode[string]
70
+ except IndexError:
71
+ return None
72
+
73
+
74
+ def parse_simple_range(node: Node) -> SimpleRange | None: # ruff: ignore[complex-structure, too-many-branches]
75
+ """
76
+ Create a SimpleRange from a treesitter node.
77
+
78
+ Raises
79
+ ------
80
+ NodeExtraChildError:
81
+ If `node.children` does not have 2 elements.
82
+ NodeMissingChildError:
83
+ If `node.type` is not `simple_range`.
84
+ NodeTextIsInvalidError:
85
+ If the direction in `node` could not be parsed.
86
+ NodeTextIsNoneError:
87
+ If `node` or any relevant subnode doesn't define `text`.
88
+
89
+ """
90
+ if node.type != "simple_range":
91
+ raise NodeMissingChildError(node, "simple_range")
92
+ if node.text is None or len(node.text) == 0:
93
+ raise NodeTextIsNoneError(node)
94
+ if len(node.children) != 3: # ruff: ignore[magic-value-comparison]
95
+ raise NodeExtraChildError(node, "all children", 3)
96
+ left = node.child(0)
97
+ if left is None:
98
+ raise NodeMissingChildError(node, "first-child")
99
+ if left.type != "simple_expression":
100
+ NotImplementedWarning.warn_child_type(left)
101
+ return None
102
+ if left.text is None or len(left.text) == 0:
103
+ raise NodeTextIsNoneError(left)
104
+ direction_node = node.child(1)
105
+ if direction_node is None:
106
+ raise NodeMissingChildError(node, "second-child")
107
+ if len(direction_node.type) == 0:
108
+ NotImplementedWarning.warn_child_type(direction_node)
109
+ return None
110
+ if direction_node.text is None or len(direction_node.text) == 0:
111
+ raise NodeTextIsNoneError(direction_node)
112
+ direction_str = direction_node.text.decode("utf-8")
113
+ right = node.child(2)
114
+ if right is None:
115
+ raise NodeMissingChildError(node, "third-child")
116
+ if right.type != "simple_expression":
117
+ NotImplementedWarning.warn_child_type(right)
118
+ return None
119
+ if right.text is None or len(right.text) == 0:
120
+ raise NodeTextIsNoneError(right)
121
+ left_expr = parse_simple_expression(left)
122
+ if left_expr is None:
123
+ return None
124
+ right_expr = parse_simple_expression(right)
125
+ if right_expr is None:
126
+ return None
127
+ direction = parse_direction(direction_str)
128
+ if direction is None:
129
+ raise NodeTextIsInvalidError(
130
+ node,
131
+ f"'{direction_str}' is not a valid VHDL direction",
132
+ )
133
+ return inject_node(SimpleRange(left_expr, right_expr, direction), node)
134
+
135
+
136
+ def parse_waveform_element(node: Node) -> WaveformElement | None:
137
+ """Create a WaveformElement from a treesitter node."""
138
+ if node.type != "waveform_element":
139
+ return None
140
+ simple_expression_node = None
141
+ for child in node.children:
142
+ if child.type == "simple_expression":
143
+ simple_expression_node = child
144
+ break
145
+ if simple_expression_node is None:
146
+ NotImplementedWarning.warn(
147
+ "waveform_element expects a 'simple_expression' child",
148
+ node,
149
+ )
150
+ return None
151
+ expression = parse_simple_expression(simple_expression_node)
152
+ if expression is None:
153
+ return None
154
+ return inject_node(WaveformElement(expression), node)
@@ -0,0 +1,192 @@
1
+ """Submodule defining parsers for classes from pyVHDLModel.Concurrent."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "parse_component_instantiation",
7
+ "parse_concurrent_conditional_signal_assignment",
8
+ "parse_concurrent_simple_signal_assignment",
9
+ "parse_entity_instantiation",
10
+ ]
11
+
12
+ from typing import TYPE_CHECKING
13
+
14
+ from pyVHDLModel.Association import (
15
+ GenericAssociationItem,
16
+ PortAssociationItem,
17
+ )
18
+ from pyVHDLModel.Concurrent import (
19
+ ComponentInstantiation,
20
+ ConcurrentConditionalSignalAssignment,
21
+ ConcurrentSimpleSignalAssignment,
22
+ EntityInstantiation,
23
+ )
24
+ from pyVHDLModel.Symbol import (
25
+ ArchitectureSymbol,
26
+ ComponentInstantiationSymbol,
27
+ EntityInstantiationSymbol,
28
+ SignalSymbol,
29
+ )
30
+
31
+ from pyVHDLModelTreesitter._Association import parse_association_item
32
+ from pyVHDLModelTreesitter._Base import parse_waveform_element
33
+ from pyVHDLModelTreesitter._errors import NotImplementedWarning
34
+ from pyVHDLModelTreesitter._Name import parse_name
35
+ from pyVHDLModelTreesitter.treesitter import (
36
+ get_node,
37
+ get_node_text,
38
+ get_nodes,
39
+ inject_node,
40
+ sort_into_text_order,
41
+ )
42
+ from pyVHDLModelTreesitter.treesitter.query import (
43
+ ComponentInstantiationStatement,
44
+ )
45
+ from pyVHDLModelTreesitter.treesitter.query import (
46
+ ConcurrentConditionalSignalAssignment as ConcurrentConditionalSignalAssignmentQuery,
47
+ )
48
+ from pyVHDLModelTreesitter.treesitter.query import (
49
+ ConcurrentSimpleSignalAssignment as ConcurrentSimpleSignalAssignmentQuery,
50
+ )
51
+
52
+ if TYPE_CHECKING:
53
+ import tree_sitter
54
+
55
+
56
+ def _parse_common_instantiation(
57
+ node: tree_sitter.Node,
58
+ captures: dict[str, list[tree_sitter.Node]],
59
+ ) -> tuple[str, list[GenericAssociationItem], list[PortAssociationItem]]:
60
+ label_node = get_node(node, captures, "label")
61
+ label = get_node_text(label_node)
62
+ generic_associations = sort_into_text_order(
63
+ generic_association
64
+ for association_node in get_nodes(node, captures, "generics", optional=True)
65
+ if (
66
+ generic_association := parse_association_item(
67
+ GenericAssociationItem,
68
+ association_node,
69
+ )
70
+ )
71
+ is not None
72
+ )
73
+ port_associations = sort_into_text_order(
74
+ port_association
75
+ for association_node in get_nodes(node, captures, "ports", optional=True)
76
+ if (
77
+ port_association := parse_association_item(
78
+ PortAssociationItem,
79
+ association_node,
80
+ )
81
+ )
82
+ is not None
83
+ )
84
+ return label, generic_associations, port_associations
85
+
86
+
87
+ def parse_component_instantiation(
88
+ node: tree_sitter.Node,
89
+ ) -> ComponentInstantiation | None:
90
+ """Create a `ComponentInstantiation` from a treesitter node."""
91
+ captures = ComponentInstantiationStatement.capture(node)
92
+ label, generic_associations, port_associations = _parse_common_instantiation(
93
+ node,
94
+ captures,
95
+ )
96
+ name_node = get_node(node, captures, "component_name")
97
+ component_symbol = ComponentInstantiationSymbol(
98
+ parse_name(get_node_text(name_node)),
99
+ )
100
+ return inject_node(
101
+ ComponentInstantiation(
102
+ label=label,
103
+ componentSymbol=component_symbol,
104
+ genericAssociationItems=generic_associations,
105
+ portAssociationItems=port_associations,
106
+ ),
107
+ node,
108
+ )
109
+
110
+
111
+ def parse_concurrent_simple_signal_assignment(
112
+ node: tree_sitter.Node,
113
+ ) -> ConcurrentSimpleSignalAssignment | None:
114
+ """Create a `ConcurrentSimpleSignalAssignment` from a treesitter node."""
115
+ captures = ConcurrentSimpleSignalAssignmentQuery.capture(node)
116
+ label_node = get_node(node, captures, "label", optional=True)
117
+ label = get_node_text(label_node) if label_node is not None else None
118
+ target_node = get_node(node, captures, "lhs")
119
+ target = SignalSymbol(parse_name(get_node_text(target_node)))
120
+ waveform_node = get_node(node, captures, "rhs")
121
+ waveform = [
122
+ we
123
+ for child in waveform_node.children
124
+ if child.type == "waveform_element"
125
+ for we in [parse_waveform_element(child)]
126
+ if we is not None
127
+ ]
128
+ # TODO: label is incorrectly `str` rather than `Nullable[str]`
129
+ # ty: ignore[invalid-argument-type]
130
+ return inject_node(ConcurrentSimpleSignalAssignment(label, target, waveform), node) # type: ignore[arg-type]
131
+
132
+
133
+ def parse_concurrent_conditional_signal_assignment(
134
+ node: tree_sitter.Node,
135
+ ) -> ConcurrentConditionalSignalAssignment | None:
136
+ """Create a `ConcurrentConditionalSignalAssignment` from a treesitter node."""
137
+ captures = ConcurrentConditionalSignalAssignmentQuery.capture(node)
138
+ label_node = get_node(node, captures, "label", optional=True)
139
+ label = get_node_text(label_node) if label_node is not None else None
140
+ target_node = get_node(node, captures, "lhs")
141
+ target = SignalSymbol(parse_name(get_node_text(target_node)))
142
+ _rhs_node = get_node(node, captures, "rhs")
143
+ NotImplementedWarning.warn_incomplete_model(
144
+ ConcurrentConditionalSignalAssignment,
145
+ node,
146
+ )
147
+ return inject_node(
148
+ ConcurrentConditionalSignalAssignment(
149
+ # TODO: label is incorrectly `str` rather than `Nullable[str]`
150
+ # ty: ignore[invalid-argument-type]
151
+ label=label, # type: ignore[arg-type]
152
+ target=target,
153
+ conditionalWaveforms=[], # TODO: implement this
154
+ ),
155
+ node,
156
+ )
157
+
158
+
159
+ def parse_entity_instantiation(
160
+ node: tree_sitter.Node,
161
+ ) -> EntityInstantiation | None:
162
+ """Create an `EntityInstantiation` from a treesitter node."""
163
+ captures = ComponentInstantiationStatement.capture(node)
164
+ label, generic_associations, port_associations = _parse_common_instantiation(
165
+ node,
166
+ captures,
167
+ )
168
+ entity_str = ""
169
+ namespace_node = get_node(node, captures, "namespace", optional=True)
170
+ if namespace_node is not None:
171
+ entity_str = f"{get_node_text(namespace_node)}."
172
+ entity_node = get_node(node, captures, "entity")
173
+ entity_str += get_node_text(entity_node)
174
+ entity_symbol = EntityInstantiationSymbol(
175
+ parse_name(entity_str),
176
+ )
177
+ architecture_node = get_node(node, captures, "architecture", optional=True)
178
+ architecture_symbol = None
179
+ if architecture_node is not None:
180
+ architecture_symbol = ArchitectureSymbol(
181
+ parse_name(get_node_text(architecture_node)),
182
+ )
183
+ return inject_node(
184
+ EntityInstantiation(
185
+ label=label,
186
+ entitySymbol=entity_symbol,
187
+ architectureSymbol=architecture_symbol,
188
+ genericAssociationItems=generic_associations,
189
+ portAssociationItems=port_associations,
190
+ ),
191
+ node,
192
+ )
@@ -0,0 +1,24 @@
1
+ """Classes related to `Design`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import cast
6
+
7
+ from pyVHDLModel import Design as VHDLModel_Design
8
+ from pyVHDLModel import Library
9
+
10
+
11
+ class Design(VHDLModel_Design):
12
+ def GetLibrary( # ruff: ignore[invalid-function-name]
13
+ self,
14
+ libraryName: str, # ruff: ignore[invalid-argument-name]
15
+ ) -> Library:
16
+ library = self.Libraries.get(libraryName)
17
+ if library is not None:
18
+ return cast("Library", library)
19
+ library = Library(
20
+ libraryName,
21
+ allowBlackbox=self._allowBlackbox,
22
+ )
23
+ self.AddLibrary(library)
24
+ return library