From d3c180e03dafb74f383d762df2a9fa9820fe0109 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:29:54 -0400 Subject: [PATCH 01/44] Refactor coverage_table.py to use TypedDict --- src/vba_unit/Interpreter/coverage_table.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/vba_unit/Interpreter/coverage_table.py b/src/vba_unit/Interpreter/coverage_table.py index 30329489..dd925352 100644 --- a/src/vba_unit/Interpreter/coverage_table.py +++ b/src/vba_unit/Interpreter/coverage_table.py @@ -1,22 +1,11 @@ -from pyvba_interpreter.symbol_table import ( - FunctionDefinition, ModuleDefinition, ProjectDefinition, SymbolTable -) +from pyvba_interpreter.symbol_table import SymbolTable +from typing import TypedDict -class VbaUnitFuncDef(FunctionDefinition): - visited: bool - start_end_lines: tuple[int, int] - - -class VbaUnitModDef(ModuleDefinition): +class VbaUnitModuleExtras(TypedDict): path: str # The file path cover: bool # Track coverage on this file? coverage: list[None | int] # lines covered - functions: dict[str, VbaUnitFuncDef] # {@inheritDoc} - - -class VbaUnitProjDef(ProjectDefinition): - modules: dict[str, VbaUnitModDef] class CoverageTable(SymbolTable): From 28bb00a63d9646f7aedc707aa3aa4b2b0cfd8450 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:39:27 -0400 Subject: [PATCH 02/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 0d50faec..bef2d8fe 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -17,11 +17,16 @@ def enterProceduralModuleHeader( # noqa: N802 token_stream.fill() eof_token = token_stream.get(len(token_stream.tokens) - 1) total_lines = eof_token.line - mods = self.table.definitions[self.project_name]["modules"] - mods[self.module_name.lower()]["coverage"] = [0] * total_lines - mods[self.module_name.lower()]["cover"] = True - mods[self.module_name.lower()]["coverage"][total_lines - 1] = None - mods[self.module_name.lower()]["coverage"][ctx.start.line - 1] = 1 + name = self.module_name.lower() + mod = self.table.definitions[self.project_name]["modules"][name] + mod["extras"]["vba_unit"] = { + "coverage": [0] * total_lines, + "cover": True + } + # EOF line is ignored. + # Need to test the case where EOF is on the same line as code. + mod["extras"]["vba_unit"]["coverage"][total_lines - 1] = None + mod["coverage"][ctx.start.line - 1] = 1 def enterCommentBody( # noqa: N802 self: T, @@ -36,8 +41,9 @@ def enterCommentBody( # noqa: N802 # Comments cannot be the first token in a file, so # tokenIndex - 1 cannot be less than zero index_num = ctx.start.line - 1 + name = self.module_name.lower() mods = self.table.definitions[self.project_name]["modules"] - mods[self.module_name.lower()]["coverage"][index_num] = None + mods[name]["extras"]["vba_unit"]["coverage"][index_num] = None def enterEndOfLine( # noqa: N802 self: T, @@ -52,5 +58,6 @@ def enterEndOfLine( # noqa: N802 (is_wsc and (in_str.get(tok_ind - 1).column == 0)) ): index_num = ctx.start.line - 1 + name = self.module_name.lower() mods = self.table.definitions[self.project_name]["modules"] - mods[self.module_name.lower()]["coverage"][index_num] = None + mods[name]["extras"]["vba_unit"]["coverage"][index_num] = None From 832e3549f1a04026e077493b055355e9524024db Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:41:08 -0400 Subject: [PATCH 03/44] Update vba_unit_visitor.py --- src/vba_unit/Interpreter/vba_unit_visitor.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_visitor.py b/src/vba_unit/Interpreter/vba_unit_visitor.py index f5b91371..cda6b4e6 100644 --- a/src/vba_unit/Interpreter/vba_unit_visitor.py +++ b/src/vba_unit/Interpreter/vba_unit_visitor.py @@ -31,7 +31,8 @@ def visit(self: T, tree: Tree) -> Any: self.context_changed = False name = self.context[0] mods = self.table.definitions[name]["modules"] - coverage = mods[self.context[1]]["coverage"] + extras = mods[self.context[1]]["extras"]["vba_unit"] + coverage = extras["coverage"] coverage[line_num - 1] += 1 # Call the original visit to continue traversal return super().visit(tree) @@ -45,7 +46,7 @@ def visitFunctionDeclaration( # noqa: N802 # is there a way to prohibit it from being touched...does it matter? line_num = ctx.stop.line mods = self.table.definitions[self.context[0]]["modules"] - coverage = mods[self.context[1]]["coverage"] + coverage = mods[self.context[1]]["extras"]["vba_unit"]["coverage"] coverage[line_num - 1] += 1 return super().visitFunctionDeclaration(ctx) From 751db28bd96a0ecbcf4590996bf1afff3f472c6f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:43:48 -0400 Subject: [PATCH 04/44] Update coveralls.py --- src/vba_unit/Coverage/coveralls.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vba_unit/Coverage/coveralls.py b/src/vba_unit/Coverage/coveralls.py index 179f3a2a..6e6fdb1b 100644 --- a/src/vba_unit/Coverage/coveralls.py +++ b/src/vba_unit/Coverage/coveralls.py @@ -3,7 +3,7 @@ from typing import TypeVar from vba_unit.Coverage.coverage import Coverage from vba_unit.Coverage.git_repo import GitRepo -from vba_unit.Interpreter.coverage_table import CoverageTable, VbaUnitModDef +from pyvba_interpreter.symbol_table import SymbolTable T = TypeVar('T', bound='Coveralls') @@ -13,7 +13,7 @@ class Coveralls(Coverage): def __init__(self: T) -> None: self.endpoint = "https://coveralls.io/api/v1/jobs" self.git: GitRepo - self.table: CoverageTable + self.table: SymbolTable def generate_report(self: T) -> dict: source_files = [] @@ -35,7 +35,7 @@ def generate_report(self: T) -> dict: } return report - def file_coverage(self: T, module: VbaUnitModDef) -> dict: + def file_coverage(self: T, module: ModuleDefinition) -> dict: file_path = module["path"] with open(file_path, 'r') as f: source_code = f.read() From 3226325c6c55dc55bf4f3567a8b377ea3bd8266e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:44:15 -0400 Subject: [PATCH 05/44] Update coverage.py --- src/vba_unit/Coverage/coverage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vba_unit/Coverage/coverage.py b/src/vba_unit/Coverage/coverage.py index fb020bf4..7c88fca2 100644 --- a/src/vba_unit/Coverage/coverage.py +++ b/src/vba_unit/Coverage/coverage.py @@ -2,7 +2,7 @@ import requests from typing import TypeVar from .git_repo import GitRepo -from vba_unit.Interpreter.coverage_table import CoverageTable +from pyvba_interpreter.symbol_table import SymbolTable T = TypeVar('T', bound='Coverage') @@ -16,7 +16,7 @@ class Coverage(): """ def __init__(self: T) -> None: self.endpoint = '' - self.table: CoverageTable + self.table: SymbolTable self.git: GitRepo def generate_report(self: T) -> dict: From 45909ed38c348dacea2de497e61df4c29a7f456e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:45:13 -0400 Subject: [PATCH 06/44] Update cli.py --- src/vba_unit/cli.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vba_unit/cli.py b/src/vba_unit/cli.py index 04476844..fbdb0cfe 100644 --- a/src/vba_unit/cli.py +++ b/src/vba_unit/cli.py @@ -7,7 +7,7 @@ from typing import TypeVar from vba_unit.Coverage.coverage_factory import CovFact from vba_unit.Coverage.git_factory import GitFact -from vba_unit.Interpreter.coverage_table import VbaUnitModDef, CoverageTable +from pyvba_interpreter.symbol_table import SymbolTable from vba_unit.Interpreter.vba_unit_listener import VbaUnitListener from vba_unit.Interpreter.vba_unit_visitor import VbaUnitVisitor from vba_unit.test_fail_exception import TestFailException @@ -52,7 +52,7 @@ def main() -> None: ) args = parser.parse_args() - table = CoverageTable() + table = SymbolTable() run_tests(args.src, args.tests, args.project, table) # Submit Coverage @@ -72,7 +72,7 @@ def main() -> None: def run_tests(src: str, tests: str, - project_name: str, table: CoverageTable) -> None: + project_name: str, table: SymbolTable) -> None: test_project_name = "vbatests" # Parse source code @@ -95,7 +95,7 @@ def run_tests(src: str, tests: str, _generate_report(report) -def _parse_file(file_path: str, project: str, table: CoverageTable) -> None: +def _parse_file(file_path: str, project: str, table: SymbolTable) -> None: input_stream = FileStream(file_path, encoding="cp1252") lexer = vbaLexer(input_stream) ts = CommonTokenStream(lexer) @@ -116,7 +116,7 @@ def _parse_file(file_path: str, project: str, table: CoverageTable) -> None: def _run_all_tests( test_modules: dict[str, VbaUnitModDef], - table: CoverageTable) -> list: + table: SymbolTable) -> list: report = [] visitor = VbaUnitVisitor(table) for mod_name, module in test_modules.items(): From 6fe517d98fd930aefc65e626ad577d69e725ada5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:45:31 -0400 Subject: [PATCH 07/44] Update cli.py --- src/vba_unit/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/cli.py b/src/vba_unit/cli.py index fbdb0cfe..00cdba87 100644 --- a/src/vba_unit/cli.py +++ b/src/vba_unit/cli.py @@ -4,10 +4,10 @@ from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker from antlr4_vba.vbaLexer import vbaLexer from antlr4_vba.vbaParser import vbaParser +from pyvba_interpreter.symbol_table import SymbolTable from typing import TypeVar from vba_unit.Coverage.coverage_factory import CovFact from vba_unit.Coverage.git_factory import GitFact -from pyvba_interpreter.symbol_table import SymbolTable from vba_unit.Interpreter.vba_unit_listener import VbaUnitListener from vba_unit.Interpreter.vba_unit_visitor import VbaUnitVisitor from vba_unit.test_fail_exception import TestFailException From b86c17593a28f12156fd1896b0ded1aad261a9f8 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:48:02 -0400 Subject: [PATCH 08/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index bef2d8fe..9f32c57d 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -1,14 +1,19 @@ from antlr4_vba.vbaParser import vbaParser as Parser from antlr4_vba.vbaLexer import vbaLexer as Lexer from pyvba_interpreter.vba_listener import VbaListener -from typing import TypeVar +from typing import TypedDict, TypeVar T = TypeVar('T', bound='VbaUnitListener') -class VbaUnitListener(VbaListener): +class VbaUnitModuleExtras(TypedDict): + path: str # The file path + cover: bool # Track coverage on this file? + coverage: list[None | int] # lines covered + +class VbaUnitListener(VbaListener): def enterProceduralModuleHeader( # noqa: N802 self: T, ctx: Parser.ProceduralModuleHeaderContext) -> None: @@ -19,10 +24,12 @@ def enterProceduralModuleHeader( # noqa: N802 total_lines = eof_token.line name = self.module_name.lower() mod = self.table.definitions[self.project_name]["modules"][name] - mod["extras"]["vba_unit"] = { + extras: VbaUnitModuleExtras = { "coverage": [0] * total_lines, - "cover": True + "cover": True, + "path" = '' } + mod["extras"]["vba_unit"] = extras # EOF line is ignored. # Need to test the case where EOF is on the same line as code. mod["extras"]["vba_unit"]["coverage"][total_lines - 1] = None From 360c209f4624ec248d661c0fa035ed847b6d2198 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:48:16 -0400 Subject: [PATCH 09/44] Delete src/vba_unit/Interpreter/coverage_table.py --- src/vba_unit/Interpreter/coverage_table.py | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/vba_unit/Interpreter/coverage_table.py diff --git a/src/vba_unit/Interpreter/coverage_table.py b/src/vba_unit/Interpreter/coverage_table.py deleted file mode 100644 index dd925352..00000000 --- a/src/vba_unit/Interpreter/coverage_table.py +++ /dev/null @@ -1,12 +0,0 @@ -from pyvba_interpreter.symbol_table import SymbolTable -from typing import TypedDict - - -class VbaUnitModuleExtras(TypedDict): - path: str # The file path - cover: bool # Track coverage on this file? - coverage: list[None | int] # lines covered - - -class CoverageTable(SymbolTable): - pass From 334f78a4edef0c090cbb9dbab9254f9146f3fca6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:48:39 -0400 Subject: [PATCH 10/44] Update test_visitor.py --- tests/Unit/test_visitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/test_visitor.py b/tests/Unit/test_visitor.py index f0e3e8e7..1914aed5 100644 --- a/tests/Unit/test_visitor.py +++ b/tests/Unit/test_visitor.py @@ -1,13 +1,13 @@ from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker from antlr4_vba.vbaLexer import vbaLexer from antlr4_vba.vbaParser import vbaParser -from vba_unit.Interpreter.coverage_table import CoverageTable +from pyvba_interpreter.symbol_table import SymbolTable from vba_unit.Interpreter.vba_unit_listener import VbaUnitListener from vba_unit.Interpreter.vba_unit_visitor import VbaUnitVisitor def test_listener() -> None: - table = CoverageTable() + table = SymbolTable() input_stream = FileStream( "tests/src/VbaProject/Module1.bas", encoding="cp1252" From 3538d7ad7f0ce76b763d96baf0127a6d222422e0 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:48:53 -0400 Subject: [PATCH 11/44] Update test_listener.py --- tests/Unit/test_listener.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/test_listener.py b/tests/Unit/test_listener.py index 980d93f2..837a09c9 100644 --- a/tests/Unit/test_listener.py +++ b/tests/Unit/test_listener.py @@ -1,12 +1,12 @@ from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker from antlr4_vba.vbaLexer import vbaLexer from antlr4_vba.vbaParser import vbaParser -from vba_unit.Interpreter.coverage_table import CoverageTable +from pyvba_interpreter.symbol_table import SymbolTable from vba_unit.Interpreter.vba_unit_listener import VbaUnitListener def test_listener() -> None: - table = CoverageTable() + table = SymbolTable() input_stream = FileStream( "tests/src/VbaProject/Module1.bas", encoding="cp1252" From bcd88b2cf1f7752ff5dd9aad648371565a340b2d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:50:28 -0400 Subject: [PATCH 12/44] Update coveralls.py --- src/vba_unit/Coverage/coveralls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Coverage/coveralls.py b/src/vba_unit/Coverage/coveralls.py index 6e6fdb1b..47ff323e 100644 --- a/src/vba_unit/Coverage/coveralls.py +++ b/src/vba_unit/Coverage/coveralls.py @@ -43,5 +43,5 @@ def file_coverage(self: T, module: ModuleDefinition) -> dict: return { "name": file_path, "source_digest": digest, - "coverage": module["coverage"], + "coverage": module["extras"]["vba_unit"]["coverage"], } From d32255c5a28c2f1d842389820e8d720d099b117a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:50:50 -0400 Subject: [PATCH 13/44] Update coveralls.py --- src/vba_unit/Coverage/coveralls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Coverage/coveralls.py b/src/vba_unit/Coverage/coveralls.py index 47ff323e..c2027a16 100644 --- a/src/vba_unit/Coverage/coveralls.py +++ b/src/vba_unit/Coverage/coveralls.py @@ -36,7 +36,7 @@ def generate_report(self: T) -> dict: return report def file_coverage(self: T, module: ModuleDefinition) -> dict: - file_path = module["path"] + file_path = module["extras"]["vba_unit"]["path"] with open(file_path, 'r') as f: source_code = f.read() digest = hashlib.md5(source_code.encode('utf-8')).hexdigest() From e9da89bf2f51eef5436692db3eb94da223bfa97a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:52:24 -0400 Subject: [PATCH 14/44] Update cli.py --- src/vba_unit/cli.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vba_unit/cli.py b/src/vba_unit/cli.py index 00cdba87..e7b9afc7 100644 --- a/src/vba_unit/cli.py +++ b/src/vba_unit/cli.py @@ -107,11 +107,12 @@ def _parse_file(file_path: str, project: str, table: SymbolTable) -> None: walker.walk(listener, tree) mod_name = listener.module_name.lower() project = project.lower() - table.definitions[project]["modules"][mod_name]["path"] = file_path + extras = table.definitions[project]["modules"][mod_name]["extras"]["vba_unit"] + extras["path"] = file_path if project == "vbatests": - table.definitions[project]["modules"][mod_name]["cover"] = False + extras["cover"] = False else: - table.definitions[project]["modules"][mod_name]["cover"] = True + extras["cover"] = True def _run_all_tests( From 47226921263c718805ff1ecc19a2e82f088f9759 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:56:37 -0400 Subject: [PATCH 15/44] Import ModuleDefinition in coveralls.py --- src/vba_unit/Coverage/coveralls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Coverage/coveralls.py b/src/vba_unit/Coverage/coveralls.py index c2027a16..221459e4 100644 --- a/src/vba_unit/Coverage/coveralls.py +++ b/src/vba_unit/Coverage/coveralls.py @@ -3,7 +3,7 @@ from typing import TypeVar from vba_unit.Coverage.coverage import Coverage from vba_unit.Coverage.git_repo import GitRepo -from pyvba_interpreter.symbol_table import SymbolTable +from pyvba_interpreter.symbol_table import ModuleDefinition, SymbolTable T = TypeVar('T', bound='Coveralls') From dad6b0f5f181b085910cd487be9a3fb7633f3992 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:57:29 -0400 Subject: [PATCH 16/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 9f32c57d..ceb55ebc 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -27,7 +27,7 @@ def enterProceduralModuleHeader( # noqa: N802 extras: VbaUnitModuleExtras = { "coverage": [0] * total_lines, "cover": True, - "path" = '' + "path": '' } mod["extras"]["vba_unit"] = extras # EOF line is ignored. From 4b9995ca78f82dfbf3f5dcff19a87272971d2edf Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 10:58:35 -0400 Subject: [PATCH 17/44] Update cli.py --- src/vba_unit/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vba_unit/cli.py b/src/vba_unit/cli.py index e7b9afc7..c4f2e3d8 100644 --- a/src/vba_unit/cli.py +++ b/src/vba_unit/cli.py @@ -4,7 +4,7 @@ from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker from antlr4_vba.vbaLexer import vbaLexer from antlr4_vba.vbaParser import vbaParser -from pyvba_interpreter.symbol_table import SymbolTable +from pyvba_interpreter.symbol_table import ModuleDefinition, SymbolTable from typing import TypeVar from vba_unit.Coverage.coverage_factory import CovFact from vba_unit.Coverage.git_factory import GitFact @@ -116,7 +116,7 @@ def _parse_file(file_path: str, project: str, table: SymbolTable) -> None: def _run_all_tests( - test_modules: dict[str, VbaUnitModDef], + test_modules: dict[str, ModuleDefinition], table: SymbolTable) -> list: report = [] visitor = VbaUnitVisitor(table) From eda5f47f077e218afc984867e0a17b8a8b4f02dc Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:00:45 -0400 Subject: [PATCH 18/44] Update vba_unit_visitor.py --- src/vba_unit/Interpreter/vba_unit_visitor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_visitor.py b/src/vba_unit/Interpreter/vba_unit_visitor.py index cda6b4e6..2140d32e 100644 --- a/src/vba_unit/Interpreter/vba_unit_visitor.py +++ b/src/vba_unit/Interpreter/vba_unit_visitor.py @@ -1,10 +1,10 @@ from antlr4.tree.Tree import Tree from antlr4 import ParserRuleContext from antlr4_vba.vbaParser import vbaParser as Parser +from pyvba_interpreter.symbol_table import FunctionDefinition, SymbolTable from pyvba_interpreter.vba_visitor import VbaVisitor from typing import Any, TypeVar from vba_unit.test_fail_exception import TestFailException -from .coverage_table import VbaUnitFuncDef, CoverageTable T = TypeVar('T', bound='VbaUnitVisitor') @@ -12,7 +12,7 @@ class VbaUnitVisitor(VbaVisitor): - def __init__(self: T, table: CoverageTable) -> None: + def __init__(self: T, table: SymbolTable) -> None: self.current_line = 0 super().__init__(table) @@ -61,7 +61,7 @@ def visitAssertStatement( # noqa: N802 raise TestFailException() def run_function(self: T, - defn: VbaUnitFuncDef, + defn: FunctionDefinition, args: list[Any]) -> Any: prev_line = self.current_line if (self.context[0] != defn["project"] or From e7ba7f7133ca0d1a61cb50cc3326795401192556 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:05:31 -0400 Subject: [PATCH 19/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index ceb55ebc..6f6d3fad 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -7,7 +7,7 @@ T = TypeVar('T', bound='VbaUnitListener') -class VbaUnitModuleExtras(TypedDict): +class VbaUnitModuleextra(TypedDict): path: str # The file path cover: bool # Track coverage on this file? coverage: list[None | int] # lines covered @@ -24,15 +24,15 @@ def enterProceduralModuleHeader( # noqa: N802 total_lines = eof_token.line name = self.module_name.lower() mod = self.table.definitions[self.project_name]["modules"][name] - extras: VbaUnitModuleExtras = { + extra: VbaUnitModuleextra = { "coverage": [0] * total_lines, "cover": True, "path": '' } - mod["extras"]["vba_unit"] = extras + mod["extra"]["vba_unit"] = extra # EOF line is ignored. # Need to test the case where EOF is on the same line as code. - mod["extras"]["vba_unit"]["coverage"][total_lines - 1] = None + mod["extra"]["vba_unit"]["coverage"][total_lines - 1] = None mod["coverage"][ctx.start.line - 1] = 1 def enterCommentBody( # noqa: N802 @@ -50,7 +50,7 @@ def enterCommentBody( # noqa: N802 index_num = ctx.start.line - 1 name = self.module_name.lower() mods = self.table.definitions[self.project_name]["modules"] - mods[name]["extras"]["vba_unit"]["coverage"][index_num] = None + mods[name]["extra"]["vba_unit"]["coverage"][index_num] = None def enterEndOfLine( # noqa: N802 self: T, @@ -67,4 +67,4 @@ def enterEndOfLine( # noqa: N802 index_num = ctx.start.line - 1 name = self.module_name.lower() mods = self.table.definitions[self.project_name]["modules"] - mods[name]["extras"]["vba_unit"]["coverage"][index_num] = None + mods[name]["extra"]["vba_unit"]["coverage"][index_num] = None From 6f37bd43246b865474a84d088075bd758bc08c35 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:05:51 -0400 Subject: [PATCH 20/44] Fix coverage access in vba_unit_visitor.py --- src/vba_unit/Interpreter/vba_unit_visitor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_visitor.py b/src/vba_unit/Interpreter/vba_unit_visitor.py index 2140d32e..66ab9270 100644 --- a/src/vba_unit/Interpreter/vba_unit_visitor.py +++ b/src/vba_unit/Interpreter/vba_unit_visitor.py @@ -31,8 +31,8 @@ def visit(self: T, tree: Tree) -> Any: self.context_changed = False name = self.context[0] mods = self.table.definitions[name]["modules"] - extras = mods[self.context[1]]["extras"]["vba_unit"] - coverage = extras["coverage"] + extra = mods[self.context[1]]["extra"]["vba_unit"] + coverage = extra["coverage"] coverage[line_num - 1] += 1 # Call the original visit to continue traversal return super().visit(tree) @@ -46,7 +46,7 @@ def visitFunctionDeclaration( # noqa: N802 # is there a way to prohibit it from being touched...does it matter? line_num = ctx.stop.line mods = self.table.definitions[self.context[0]]["modules"] - coverage = mods[self.context[1]]["extras"]["vba_unit"]["coverage"] + coverage = mods[self.context[1]]["extra"]["vba_unit"]["coverage"] coverage[line_num - 1] += 1 return super().visitFunctionDeclaration(ctx) From 4674aa6d6c4e8007a5b68018fdcb909757212313 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:06:10 -0400 Subject: [PATCH 21/44] Update coveralls.py --- src/vba_unit/Coverage/coveralls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vba_unit/Coverage/coveralls.py b/src/vba_unit/Coverage/coveralls.py index 221459e4..c8016dc0 100644 --- a/src/vba_unit/Coverage/coveralls.py +++ b/src/vba_unit/Coverage/coveralls.py @@ -36,12 +36,12 @@ def generate_report(self: T) -> dict: return report def file_coverage(self: T, module: ModuleDefinition) -> dict: - file_path = module["extras"]["vba_unit"]["path"] + file_path = module["extra"]["vba_unit"]["path"] with open(file_path, 'r') as f: source_code = f.read() digest = hashlib.md5(source_code.encode('utf-8')).hexdigest() return { "name": file_path, "source_digest": digest, - "coverage": module["extras"]["vba_unit"]["coverage"], + "coverage": module["extra"]["vba_unit"]["coverage"], } From 803b762d5ff19d8ce99fbe1e63c4970e3090b4cb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:06:30 -0400 Subject: [PATCH 22/44] Update cli.py --- src/vba_unit/cli.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vba_unit/cli.py b/src/vba_unit/cli.py index c4f2e3d8..359015f4 100644 --- a/src/vba_unit/cli.py +++ b/src/vba_unit/cli.py @@ -107,12 +107,12 @@ def _parse_file(file_path: str, project: str, table: SymbolTable) -> None: walker.walk(listener, tree) mod_name = listener.module_name.lower() project = project.lower() - extras = table.definitions[project]["modules"][mod_name]["extras"]["vba_unit"] - extras["path"] = file_path + extra = table.definitions[project]["modules"][mod_name]["extra"]["vba_unit"] + extra["path"] = file_path if project == "vbatests": - extras["cover"] = False + extra["cover"] = False else: - extras["cover"] = True + extra["cover"] = True def _run_all_tests( From 9427fd69a59288869a153e0db2c50432e8cd961e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:09:45 -0400 Subject: [PATCH 23/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 6f6d3fad..e8a5d7ea 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -33,7 +33,7 @@ def enterProceduralModuleHeader( # noqa: N802 # EOF line is ignored. # Need to test the case where EOF is on the same line as code. mod["extra"]["vba_unit"]["coverage"][total_lines - 1] = None - mod["coverage"][ctx.start.line - 1] = 1 + mod["extra"]["vba_unit"]["coverage"][ctx.start.line - 1] = 1 def enterCommentBody( # noqa: N802 self: T, From 8c499ffef87d090bc430bcbd2c5c26785b5cf453 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:11:25 -0400 Subject: [PATCH 24/44] Update test_listener.py --- tests/Unit/test_listener.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/test_listener.py b/tests/Unit/test_listener.py index 837a09c9..ba52e6fe 100644 --- a/tests/Unit/test_listener.py +++ b/tests/Unit/test_listener.py @@ -19,9 +19,9 @@ def test_listener() -> None: listener.parser = parser walker = ParseTreeWalker() walker.walk(listener, tree) + extra = table.definitions["vbaproject"]["modules"]["module1"]["extra"]["vba_unit"] + assert extra["cover"] - assert table.definitions["vbaproject"]["modules"]["module1"]["cover"] - - result = table.definitions["vbaproject"]["modules"]["module1"]["coverage"] + result = extra["coverage"] expected = [1, 0, None, 0, 0, None] assert result == expected From 02b9ebd904f426b02515d626d752580eea1d5330 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:12:34 -0400 Subject: [PATCH 25/44] Update test_visitor.py --- tests/Unit/test_visitor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/test_visitor.py b/tests/Unit/test_visitor.py index 1914aed5..b635272e 100644 --- a/tests/Unit/test_visitor.py +++ b/tests/Unit/test_visitor.py @@ -6,7 +6,7 @@ from vba_unit.Interpreter.vba_unit_visitor import VbaUnitVisitor -def test_listener() -> None: +def test_visitor() -> None: table = SymbolTable() input_stream = FileStream( "tests/src/VbaProject/Module1.bas", @@ -23,6 +23,6 @@ def test_listener() -> None: visitor = VbaUnitVisitor(table) mod = table.definitions["vbaproject"]["modules"]["module1"] func = mod["functions"]["foo"] - assert mod["coverage"][3] == 0 + assert mod["extra"]["vba_unit"]["coverage"][3] == 0 visitor.run_function(func, []) - assert mod["coverage"][3] == 1 + assert mod["extra"]["vba_unit"]["coverage"][3] == 1 From f8f5f23a7e1bba719b9d481e73794c30d059db16 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:14:56 -0400 Subject: [PATCH 26/44] Update vba_unit_visitor.py --- src/vba_unit/Interpreter/vba_unit_visitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_visitor.py b/src/vba_unit/Interpreter/vba_unit_visitor.py index 66ab9270..27278367 100644 --- a/src/vba_unit/Interpreter/vba_unit_visitor.py +++ b/src/vba_unit/Interpreter/vba_unit_visitor.py @@ -24,7 +24,7 @@ def visit(self: T, tree: Tree) -> Any: prev_line = self.current_line if tok is not None: mods = self.table.definitions[self.context[0]]["modules"] - if mods[self.context[1]]["cover"]: + if mods[self.context[1]]["extra"]["vba_unit"]["cover"]: line_num = tok.line if line_num != self.current_line: self.current_line = line_num From ec1bfcb6e03f7321980b09cafd4be7e19df3fb47 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:15:53 -0400 Subject: [PATCH 27/44] Update cli.py --- src/vba_unit/cli.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vba_unit/cli.py b/src/vba_unit/cli.py index 359015f4..4513572f 100644 --- a/src/vba_unit/cli.py +++ b/src/vba_unit/cli.py @@ -107,7 +107,8 @@ def _parse_file(file_path: str, project: str, table: SymbolTable) -> None: walker.walk(listener, tree) mod_name = listener.module_name.lower() project = project.lower() - extra = table.definitions[project]["modules"][mod_name]["extra"]["vba_unit"] + mod = table.definitions[project]["modules"][mod_name] + extra = mod["extra"]["vba_unit"] extra["path"] = file_path if project == "vbatests": extra["cover"] = False From 3e9697b7fbe6b5ae3a9051b9a78303cf8a63fdf7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:16:58 -0400 Subject: [PATCH 28/44] Update coveralls.py --- src/vba_unit/Coverage/coveralls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Coverage/coveralls.py b/src/vba_unit/Coverage/coveralls.py index c8016dc0..481896dc 100644 --- a/src/vba_unit/Coverage/coveralls.py +++ b/src/vba_unit/Coverage/coveralls.py @@ -19,7 +19,7 @@ def generate_report(self: T) -> dict: source_files = [] for lib in self.table.definitions.values(): for module in lib["modules"].values(): - if module["cover"]: + if module["extra"]["vba_unit"]["cover"]: file_cov = self.file_coverage(module) source_files.append(file_cov) From 00e71f91c5d5a53cf563967c33506b2eacaf2a2b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:19:08 -0400 Subject: [PATCH 29/44] Update test_coveralls.py --- tests/Unit/test_coveralls.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/Unit/test_coveralls.py b/tests/Unit/test_coveralls.py index b5cb0770..77a98615 100644 --- a/tests/Unit/test_coveralls.py +++ b/tests/Unit/test_coveralls.py @@ -37,10 +37,12 @@ def __init__(self: T) -> None: "modules": { "roots": { "name": "roots", - "cover": True, - "coverage": [1, None, None, None, None, None, None, - None, None, None, None, 1, 1, 1], - "path": 'src/Modules/Roots.bas' + "extra": { + "cover": True, + "coverage": [1, None, None, None, None, None, None, + None, None, None, None, 1, 1, 1], + "path": 'src/Modules/Roots.bas' + } } } } From 5ce86d6367ae0cfd1061a494f69c460384849a5e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:19:59 -0400 Subject: [PATCH 30/44] Update test_listener.py --- tests/Unit/test_listener.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Unit/test_listener.py b/tests/Unit/test_listener.py index ba52e6fe..945e7f12 100644 --- a/tests/Unit/test_listener.py +++ b/tests/Unit/test_listener.py @@ -19,7 +19,8 @@ def test_listener() -> None: listener.parser = parser walker = ParseTreeWalker() walker.walk(listener, tree) - extra = table.definitions["vbaproject"]["modules"]["module1"]["extra"]["vba_unit"] + mod = table.definitions["vbaproject"]["modules"]["module1"] + extra = mod["extra"]["vba_unit"] assert extra["cover"] result = extra["coverage"] From 653fa7b75fbaa9ac3b8e6b45665466cc4422ec80 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:20:49 -0400 Subject: [PATCH 31/44] Update test_coveralls.py --- tests/Unit/test_coveralls.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/Unit/test_coveralls.py b/tests/Unit/test_coveralls.py index 77a98615..bc5443b6 100644 --- a/tests/Unit/test_coveralls.py +++ b/tests/Unit/test_coveralls.py @@ -38,10 +38,12 @@ def __init__(self: T) -> None: "roots": { "name": "roots", "extra": { - "cover": True, - "coverage": [1, None, None, None, None, None, None, - None, None, None, None, 1, 1, 1], - "path": 'src/Modules/Roots.bas' + "vba_unit": { + "cover": True, + "coverage": [1, None, None, None, None, None, None, + None, None, None, None, 1, 1, 1], + "path": 'src/Modules/Roots.bas' + } } } } From b1eae345f391f35869932d098a1c9112e01515c6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:22:11 -0400 Subject: [PATCH 32/44] Update test_coveralls.py --- tests/Unit/test_coveralls.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/Unit/test_coveralls.py b/tests/Unit/test_coveralls.py index bc5443b6..4f8e57b5 100644 --- a/tests/Unit/test_coveralls.py +++ b/tests/Unit/test_coveralls.py @@ -40,8 +40,10 @@ def __init__(self: T) -> None: "extra": { "vba_unit": { "cover": True, - "coverage": [1, None, None, None, None, None, None, - None, None, None, None, 1, 1, 1], + "coverage": [1, None, None, None, + None, None, None, + None, None, None, None, + 1, 1, 1], "path": 'src/Modules/Roots.bas' } } From 99924c13581e63ce0c02569a4762da264e9a0728 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:27:59 -0400 Subject: [PATCH 33/44] Update vba_unit_visitor.py --- src/vba_unit/Interpreter/vba_unit_visitor.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_visitor.py b/src/vba_unit/Interpreter/vba_unit_visitor.py index 27278367..8cbd4839 100644 --- a/src/vba_unit/Interpreter/vba_unit_visitor.py +++ b/src/vba_unit/Interpreter/vba_unit_visitor.py @@ -1,7 +1,9 @@ from antlr4.tree.Tree import Tree from antlr4 import ParserRuleContext from antlr4_vba.vbaParser import vbaParser as Parser -from pyvba_interpreter.symbol_table import FunctionDefinition, SymbolTable +from pyvba_interpreter.symbol_table import ( + FunctionDefinition, LibraryDefinition, SymbolTable +) from pyvba_interpreter.vba_visitor import VbaVisitor from typing import Any, TypeVar from vba_unit.test_fail_exception import TestFailException @@ -44,10 +46,11 @@ def visitFunctionDeclaration( # noqa: N802 # Touch the end function statement # If there is an Exit Function statement immediately beore the end, # is there a way to prohibit it from being touched...does it matter? - line_num = ctx.stop.line - mods = self.table.definitions[self.context[0]]["modules"] - coverage = mods[self.context[1]]["extra"]["vba_unit"]["coverage"] - coverage[line_num - 1] += 1 + if ctx.stop is not None: + line_num = ctx.stop.line + mods = self.table.definitions[self.context[0]]["modules"] + coverage = mods[self.context[1]]["extra"]["vba_unit"]["coverage"] + coverage[line_num - 1] += 1 return super().visitFunctionDeclaration(ctx) @@ -61,7 +64,7 @@ def visitAssertStatement( # noqa: N802 raise TestFailException() def run_function(self: T, - defn: FunctionDefinition, + defn: FunctionDefinition | LibraryDefinition, args: list[Any]) -> Any: prev_line = self.current_line if (self.context[0] != defn["project"] or From daf7fb6f6742c84b0edac5f4dea907f88f96b52b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:31:36 -0400 Subject: [PATCH 34/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index e8a5d7ea..27f9058d 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -14,6 +14,10 @@ class VbaUnitModuleextra(TypedDict): class VbaUnitListener(VbaListener): + def __init__(self: T, project: str, table: SymbolTable) -> None: + self.parser: Parser + super().__init__(project, table) + def enterProceduralModuleHeader( # noqa: N802 self: T, ctx: Parser.ProceduralModuleHeaderContext) -> None: From 65c8a5ce3b49d98d0b8221fed01a717f52e4ee57 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:32:33 -0400 Subject: [PATCH 35/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 27f9058d..320d8287 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -1,5 +1,6 @@ from antlr4_vba.vbaParser import vbaParser as Parser from antlr4_vba.vbaLexer import vbaLexer as Lexer +from pyvba_interpreter.symbol_table import SymbolTable from pyvba_interpreter.vba_listener import VbaListener from typing import TypedDict, TypeVar From 1f3162603915331a3ba456a71b8578bb9a332c76 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:37:08 -0400 Subject: [PATCH 36/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 320d8287..23c611db 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -38,7 +38,8 @@ def enterProceduralModuleHeader( # noqa: N802 # EOF line is ignored. # Need to test the case where EOF is on the same line as code. mod["extra"]["vba_unit"]["coverage"][total_lines - 1] = None - mod["extra"]["vba_unit"]["coverage"][ctx.start.line - 1] = 1 + if ctx.start is not None: + mod["extra"]["vba_unit"]["coverage"][ctx.start.line - 1] = 1 def enterCommentBody( # noqa: N802 self: T, From 0f1df650b0cc319050a1f59f3d52b600322a491b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:39:53 -0400 Subject: [PATCH 37/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 23c611db..8613aa47 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -1,3 +1,4 @@ +from antlr4 import CommonTokenStream from antlr4_vba.vbaParser import vbaParser as Parser from antlr4_vba.vbaLexer import vbaLexer as Lexer from pyvba_interpreter.symbol_table import SymbolTable @@ -23,7 +24,7 @@ def enterProceduralModuleHeader( # noqa: N802 self: T, ctx: Parser.ProceduralModuleHeaderContext) -> None: super().enterProceduralModuleHeader(ctx) - token_stream = self.parser.getInputStream() + token_stream: CommonTokenStream = self.parser.getInputStream() token_stream.fill() eof_token = token_stream.get(len(token_stream.tokens) - 1) total_lines = eof_token.line From 6b8978f22f4f13bc141b6f40dafebd921a0240d2 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:41:19 -0400 Subject: [PATCH 38/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 8613aa47..147aa7e9 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -49,7 +49,7 @@ def enterCommentBody( # noqa: N802 # Check if the token starts at column 1 or if the token before this is # a wsc and it starts at column 1 in_str = self.parser.getInputStream() - if ctx.start is not None: + if ctx.start is not None and ctx.start.tokenIndex is not None: if (ctx.start.column == 0 or in_str.get(ctx.start.tokenIndex - 1).column == 0): # Comments cannot be the first token in a file, so From d2921c75b5055245486a2f3526ea5b95a285c2d5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:42:09 -0400 Subject: [PATCH 39/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 147aa7e9..a34c500b 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -48,7 +48,7 @@ def enterCommentBody( # noqa: N802 super().enterCommentBody(ctx) # Check if the token starts at column 1 or if the token before this is # a wsc and it starts at column 1 - in_str = self.parser.getInputStream() + in_str: CommonTokenStream = self.parser.getInputStream() if ctx.start is not None and ctx.start.tokenIndex is not None: if (ctx.start.column == 0 or in_str.get(ctx.start.tokenIndex - 1).column == 0): @@ -63,7 +63,7 @@ def enterEndOfLine( # noqa: N802 self: T, ctx: Parser.EndOfLineContext) -> None: super().enterEndOfLine(ctx) - in_str = self.parser.getInputStream() + in_str: CommonTokenStream = self.parser.getInputStream() if ctx.start is not None: tok_ind = ctx.start.tokenIndex is_wsc = in_str.get(tok_ind - 1).type == Lexer.WS From 3236028f2a9222f1da0c43611026d88875a6f768 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:45:01 -0400 Subject: [PATCH 40/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index a34c500b..5f9380fc 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -24,7 +24,7 @@ def enterProceduralModuleHeader( # noqa: N802 self: T, ctx: Parser.ProceduralModuleHeaderContext) -> None: super().enterProceduralModuleHeader(ctx) - token_stream: CommonTokenStream = self.parser.getInputStream() + token_stream = self.parser.getTokenStream() token_stream.fill() eof_token = token_stream.get(len(token_stream.tokens) - 1) total_lines = eof_token.line From 0260d3ec8d7d9cbc04e073f4465e6bf57f1b8430 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:47:00 -0400 Subject: [PATCH 41/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 5f9380fc..2c2914f4 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -24,7 +24,7 @@ def enterProceduralModuleHeader( # noqa: N802 self: T, ctx: Parser.ProceduralModuleHeaderContext) -> None: super().enterProceduralModuleHeader(ctx) - token_stream = self.parser.getTokenStream() + token_stream = cast(CommonTokenStream, self.parser.getTokenStream()) token_stream.fill() eof_token = token_stream.get(len(token_stream.tokens) - 1) total_lines = eof_token.line @@ -48,7 +48,7 @@ def enterCommentBody( # noqa: N802 super().enterCommentBody(ctx) # Check if the token starts at column 1 or if the token before this is # a wsc and it starts at column 1 - in_str: CommonTokenStream = self.parser.getInputStream() + in_str = cast(CommonTokenStream, self.parser.getTokenStream()) if ctx.start is not None and ctx.start.tokenIndex is not None: if (ctx.start.column == 0 or in_str.get(ctx.start.tokenIndex - 1).column == 0): @@ -63,7 +63,7 @@ def enterEndOfLine( # noqa: N802 self: T, ctx: Parser.EndOfLineContext) -> None: super().enterEndOfLine(ctx) - in_str: CommonTokenStream = self.parser.getInputStream() + in_str = cast(CommonTokenStream, self.parser.getTokenStream()) if ctx.start is not None: tok_ind = ctx.start.tokenIndex is_wsc = in_str.get(tok_ind - 1).type == Lexer.WS From 0554dfb80fef6f4b4564952e042f8b15c331fd92 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:48:32 -0400 Subject: [PATCH 42/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 2c2914f4..5aa73972 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -3,7 +3,7 @@ from antlr4_vba.vbaLexer import vbaLexer as Lexer from pyvba_interpreter.symbol_table import SymbolTable from pyvba_interpreter.vba_listener import VbaListener -from typing import TypedDict, TypeVar +from typing import casy, TypedDict, TypeVar T = TypeVar('T', bound='VbaUnitListener') From 8084c5d24517d5de6390f3c91d0fefda7b4dd03c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:48:42 -0400 Subject: [PATCH 43/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index 5aa73972..bd4038cc 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -3,7 +3,7 @@ from antlr4_vba.vbaLexer import vbaLexer as Lexer from pyvba_interpreter.symbol_table import SymbolTable from pyvba_interpreter.vba_listener import VbaListener -from typing import casy, TypedDict, TypeVar +from typing import cast, TypedDict, TypeVar T = TypeVar('T', bound='VbaUnitListener') From 6d12f3b37f513351951e571dde7839bf8d4f1767 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 8 May 2026 11:51:43 -0400 Subject: [PATCH 44/44] Update vba_unit_listener.py --- src/vba_unit/Interpreter/vba_unit_listener.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vba_unit/Interpreter/vba_unit_listener.py b/src/vba_unit/Interpreter/vba_unit_listener.py index bd4038cc..79ec9502 100644 --- a/src/vba_unit/Interpreter/vba_unit_listener.py +++ b/src/vba_unit/Interpreter/vba_unit_listener.py @@ -64,7 +64,7 @@ def enterEndOfLine( # noqa: N802 ctx: Parser.EndOfLineContext) -> None: super().enterEndOfLine(ctx) in_str = cast(CommonTokenStream, self.parser.getTokenStream()) - if ctx.start is not None: + if ctx.start is not None and ctx.start.tokenIndex is not None: tok_ind = ctx.start.tokenIndex is_wsc = in_str.get(tok_ind - 1).type == Lexer.WS if (