[Dexter] Associate parser errors with correct file (#66765)

Currently if Dexter encounters a parser error with a command, the resulting
error message will refer to the most recently declared file (i.e. the source
file it is testing) rather than the file containing the command itself. This
patch fixes this so that parser errors point towards the correct location.
This commit is contained in:
Ben Mudd 2023-09-19 13:01:32 +01:00 committed by Stephen Tozer
parent a292e7edf8
commit 9120e85448
2 changed files with 28 additions and 12 deletions

View File

@ -13,7 +13,7 @@ import os
import unittest
from copy import copy
from pathlib import PurePath
from collections import defaultdict, OrderedDict
from collections import defaultdict, OrderedDict, namedtuple
from dex.utils.Exceptions import CommandParseError, NonFloatValueInCommand
@ -83,7 +83,7 @@ def _merge_subcommands(command_name: str, valid_commands: dict) -> dict:
def _build_command(
command_type, labels, addresses, raw_text: str, path: str, lineno: str
command_type, labels, addresses, raw_text: str, path, lineno: str
) -> CommandBase:
"""Build a command object from raw text.
@ -100,11 +100,13 @@ def _build_command(
line = labels.get(label_name, None)
if line != None:
return line
raise format_unresolved_label_err(label_name, raw_text, path, lineno)
raise format_unresolved_label_err(label_name, raw_text, path.base, lineno)
def get_address_object(address_name: str, offset: int = 0):
if address_name not in addresses:
raise format_undeclared_address_err(address_name, raw_text, path, lineno)
raise format_undeclared_address_err(
address_name, raw_text, path.base, lineno
)
return AddressExpression(address_name, offset)
valid_commands = _merge_subcommands(
@ -120,7 +122,7 @@ def _build_command(
command = eval(raw_text, valid_commands)
# pylint: enable=eval-used
command.raw_text = raw_text
command.path = path
command.path = path.declared
command.lineno = lineno
return command
@ -267,7 +269,8 @@ def _find_all_commands_in_file(path, file_lines, valid_commands, source_root_dir
labels = {} # dict of {name: line}.
addresses = [] # list of addresses.
address_resolutions = {}
cmd_path = path
CmdPath = namedtuple("cmd_path", "base declared")
cmd_path = CmdPath(path, path)
declared_files = set()
commands = defaultdict(dict)
paren_balance = 0
@ -346,17 +349,16 @@ def _find_all_commands_in_file(path, file_lines, valid_commands, source_root_dir
elif type(command) is DexDeclareAddress:
add_address(addresses, command, path, cmd_point.get_lineno())
elif type(command) is DexDeclareFile:
cmd_path = command.declared_file
if not os.path.isabs(cmd_path):
declared_path = command.declared_file
if not os.path.isabs(declared_path):
source_dir = (
source_root_dir
if source_root_dir
else os.path.dirname(path)
)
cmd_path = os.path.join(source_dir, cmd_path)
# TODO: keep stored paths as PurePaths for 'longer'.
cmd_path = str(PurePath(cmd_path))
declared_files.add(cmd_path)
declared_path = os.path.join(source_dir, declared_path)
cmd_path = CmdPath(cmd_path.base, str(PurePath(declared_path)))
declared_files.add(cmd_path.declared)
elif type(command) is DexCommandLine and "DexCommandLine" in commands:
msg = "More than one DexCommandLine in file"
raise format_parse_err(msg, path, file_lines, err_point)

View File

@ -0,0 +1,14 @@
// Purpose:
// Check that Dexter command syntax errors associate with the line and file
// they appeared in rather than the current declared file.
//
// RUN: %dexter_regression_test_build %s -o %t
// RUN: not %dexter_base test --binary %t --debugger 'lldb' -v -- %s \
// RUN: | FileCheck %s --implicit-check-not=FAIL-FILENAME-MATCH
// CHECK: err_syntax_dexdeclarefile.cpp(14): Undeclared address: 'not_been_declared'
int main() { return 0; }
// DexDeclareFile('FAIL-FILENAME-MATCH')
// DexExpectWatchValue('example', address('not_been_declared'))