mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-24 17:04:17 +00:00
(Proposal) Adjustments to "decomp" language (#308)
* Adjustments to "decomp" language * Fix a comment * Fix accidental clang-formatting * Fix order * Fix order * Remove junk * Fix OFFSET * Adjustments based on new suggestions * Annotate globals * Globals in ISLE * More globals * Merge from parser2 branch * Allow prepending space for exact marker match * To eliminate noise, require the 0x prefix on offset for marker match * fix test from previous * Count tab stops for indented functions to reduce MISSED_END_OF_FUNCTION noise * FUNCTION to SYNTHETIC where needed * Missed marker conversion on SetAtomId * pylint cleanup, remove unused code * Fix unexpected function end, add more unit tests * Be more strict about synthetic name syntax * Revert "Missed marker conversion on SetAtomId" This reverts commitd87d665127. * Revert "FUNCTION to SYNTHETIC where needed" This reverts commit8c815418d2. * Implicit lookup by name for functions * Fix VTABLE SYNTHETIC and other decomp markers * Get vtable class name * Vtable marker should identify struct * No colon for SIZE comment * Update README.md * Update README.md * Update CONTRIBUTING.md * Update README.md * Update README.md * Update CONTRIBUTING.md * Update README.md * Update CONTRIBUTING.md * Fix destructor/annotation * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md --------- Co-authored-by: disinvite <disinvite@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
4f5b70013f
commit
494a556f8e
150
tools/isledecomp/tests/test_parser_statechange.py
Normal file
150
tools/isledecomp/tests/test_parser_statechange.py
Normal file
@@ -0,0 +1,150 @@
|
||||
import pytest
|
||||
from isledecomp.parser.parser import (
|
||||
ReaderState as _rs,
|
||||
DecompParser,
|
||||
)
|
||||
from isledecomp.parser.error import ParserError as _pe
|
||||
|
||||
# fmt: off
|
||||
state_change_marker_cases = [
|
||||
(_rs.SEARCH, "FUNCTION", _rs.WANT_SIG, None),
|
||||
(_rs.SEARCH, "GLOBAL", _rs.IN_GLOBAL, None),
|
||||
(_rs.SEARCH, "STUB", _rs.WANT_SIG, None),
|
||||
(_rs.SEARCH, "SYNTHETIC", _rs.IN_TEMPLATE, None),
|
||||
(_rs.SEARCH, "TEMPLATE", _rs.IN_TEMPLATE, None),
|
||||
(_rs.SEARCH, "VTABLE", _rs.IN_VTABLE, None),
|
||||
|
||||
(_rs.WANT_SIG, "FUNCTION", _rs.WANT_SIG, None),
|
||||
(_rs.WANT_SIG, "GLOBAL", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.WANT_SIG, "STUB", _rs.WANT_SIG, None),
|
||||
(_rs.WANT_SIG, "SYNTHETIC", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.WANT_SIG, "TEMPLATE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.WANT_SIG, "VTABLE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
|
||||
(_rs.IN_FUNC, "FUNCTION", _rs.WANT_SIG, _pe.MISSED_END_OF_FUNCTION),
|
||||
(_rs.IN_FUNC, "GLOBAL", _rs.IN_FUNC_GLOBAL, None),
|
||||
(_rs.IN_FUNC, "STUB", _rs.WANT_SIG, _pe.MISSED_END_OF_FUNCTION),
|
||||
(_rs.IN_FUNC, "SYNTHETIC", _rs.IN_TEMPLATE, _pe.MISSED_END_OF_FUNCTION),
|
||||
(_rs.IN_FUNC, "TEMPLATE", _rs.IN_TEMPLATE, _pe.MISSED_END_OF_FUNCTION),
|
||||
(_rs.IN_FUNC, "VTABLE", _rs.IN_VTABLE, _pe.MISSED_END_OF_FUNCTION),
|
||||
|
||||
(_rs.IN_TEMPLATE, "FUNCTION", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_TEMPLATE, "GLOBAL", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_TEMPLATE, "STUB", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_TEMPLATE, "SYNTHETIC", _rs.IN_TEMPLATE, None),
|
||||
(_rs.IN_TEMPLATE, "TEMPLATE", _rs.IN_TEMPLATE, None),
|
||||
(_rs.IN_TEMPLATE, "VTABLE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
|
||||
(_rs.WANT_CURLY, "FUNCTION", _rs.SEARCH, _pe.UNEXPECTED_MARKER),
|
||||
(_rs.WANT_CURLY, "GLOBAL", _rs.SEARCH, _pe.UNEXPECTED_MARKER),
|
||||
(_rs.WANT_CURLY, "STUB", _rs.SEARCH, _pe.UNEXPECTED_MARKER),
|
||||
(_rs.WANT_CURLY, "SYNTHETIC", _rs.SEARCH, _pe.UNEXPECTED_MARKER),
|
||||
(_rs.WANT_CURLY, "TEMPLATE", _rs.SEARCH, _pe.UNEXPECTED_MARKER),
|
||||
(_rs.WANT_CURLY, "VTABLE", _rs.SEARCH, _pe.UNEXPECTED_MARKER),
|
||||
|
||||
(_rs.IN_GLOBAL, "FUNCTION", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_GLOBAL, "GLOBAL", _rs.IN_GLOBAL, None),
|
||||
(_rs.IN_GLOBAL, "STUB", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_GLOBAL, "SYNTHETIC", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_GLOBAL, "TEMPLATE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_GLOBAL, "VTABLE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
|
||||
(_rs.IN_FUNC_GLOBAL, "FUNCTION", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_FUNC_GLOBAL, "GLOBAL", _rs.IN_FUNC_GLOBAL, None),
|
||||
(_rs.IN_FUNC_GLOBAL, "STUB", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_FUNC_GLOBAL, "SYNTHETIC", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_FUNC_GLOBAL, "TEMPLATE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_FUNC_GLOBAL, "VTABLE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
|
||||
(_rs.IN_VTABLE, "FUNCTION", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_VTABLE, "GLOBAL", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_VTABLE, "STUB", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_VTABLE, "SYNTHETIC", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_VTABLE, "TEMPLATE", _rs.SEARCH, _pe.INCOMPATIBLE_MARKER),
|
||||
(_rs.IN_VTABLE, "VTABLE", _rs.IN_VTABLE, None),
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"state, marker_type, new_state, expected_error", state_change_marker_cases
|
||||
)
|
||||
def test_state_change_by_marker(
|
||||
state: _rs, marker_type: str, new_state: _rs, expected_error: None | _pe
|
||||
):
|
||||
p = DecompParser()
|
||||
p.state = state
|
||||
mock_line = f"// {marker_type}: TEST 0x1234"
|
||||
p.read_line(mock_line)
|
||||
assert p.state == new_state
|
||||
|
||||
if expected_error is not None:
|
||||
assert len(p.alerts) > 0
|
||||
assert p.alerts[0].code == expected_error
|
||||
|
||||
|
||||
# Reading any of these lines should have no effect in ReaderState.SEARCH
|
||||
search_lines_no_effect = [
|
||||
"",
|
||||
"\t",
|
||||
" ",
|
||||
"int x = 0;",
|
||||
"// Comment",
|
||||
"/*",
|
||||
"*/",
|
||||
"/* Block comment */",
|
||||
"{",
|
||||
"}",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", search_lines_no_effect)
|
||||
def test_state_search_line(line: str):
|
||||
p = DecompParser()
|
||||
p.read_line(line)
|
||||
assert p.state == _rs.SEARCH
|
||||
assert len(p.alerts) == 0
|
||||
|
||||
|
||||
global_lines = [
|
||||
("// A comment", _rs.IN_GLOBAL),
|
||||
("", _rs.IN_GLOBAL),
|
||||
("\t", _rs.IN_GLOBAL),
|
||||
(" ", _rs.IN_GLOBAL),
|
||||
# TODO: no check for "likely" variable declaration so these all count
|
||||
("void function()", _rs.SEARCH),
|
||||
("int x = 123;", _rs.SEARCH),
|
||||
("just some text", _rs.SEARCH),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line, new_state", global_lines)
|
||||
def test_state_global_line(line: str, new_state: _rs):
|
||||
p = DecompParser()
|
||||
p.read_line("// GLOBAL: TEST 0x1234")
|
||||
assert p.state == _rs.IN_GLOBAL
|
||||
p.read_line(line)
|
||||
assert p.state == new_state
|
||||
|
||||
|
||||
# mostly same as above
|
||||
in_func_global_lines = [
|
||||
("// A comment", _rs.IN_FUNC_GLOBAL),
|
||||
("", _rs.IN_FUNC_GLOBAL),
|
||||
("\t", _rs.IN_FUNC_GLOBAL),
|
||||
(" ", _rs.IN_FUNC_GLOBAL),
|
||||
# TODO: no check for "likely" variable declaration so these all count
|
||||
("void function()", _rs.IN_FUNC),
|
||||
("int x = 123;", _rs.IN_FUNC),
|
||||
("just some text", _rs.IN_FUNC),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line, new_state", in_func_global_lines)
|
||||
def test_state_in_func_global_line(line: str, new_state: _rs):
|
||||
p = DecompParser()
|
||||
p.state = _rs.IN_FUNC
|
||||
p.read_line("// GLOBAL: TEST 0x1234")
|
||||
assert p.state == _rs.IN_FUNC_GLOBAL
|
||||
p.read_line(line)
|
||||
assert p.state == new_state
|
||||
Reference in New Issue
Block a user