mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-24 08:54:15 +00:00
parser: Identify namespaces (#499)
This commit is contained in:
73
tools/isledecomp/tests/test_curly.py
Normal file
73
tools/isledecomp/tests/test_curly.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# nyuk nyuk nyuk
|
||||
import pytest
|
||||
from isledecomp.parser.parser import CurlyManager
|
||||
from isledecomp.parser.util import sanitize_code_line
|
||||
|
||||
|
||||
@pytest.fixture(name="curly")
|
||||
def fixture_curly():
|
||||
return CurlyManager()
|
||||
|
||||
|
||||
def test_simple(curly):
|
||||
curly.read_line("namespace Test {")
|
||||
assert curly.get_prefix() == "Test"
|
||||
curly.read_line("}")
|
||||
assert curly.get_prefix() == ""
|
||||
|
||||
|
||||
def test_oneliner(curly):
|
||||
"""Should not go down into a scope for a class forward reference"""
|
||||
curly.read_line("class LegoEntity;")
|
||||
assert curly.get_prefix() == ""
|
||||
# Now make sure that we still would not consider that class name
|
||||
# even after reading the opening curly brace
|
||||
curly.read_line("if (true) {")
|
||||
assert curly.get_prefix() == ""
|
||||
|
||||
|
||||
def test_ignore_comments(curly):
|
||||
curly.read_line("namespace Test {")
|
||||
curly.read_line("// }")
|
||||
assert curly.get_prefix() == "Test"
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="todo: need a real lexer")
|
||||
def test_ignore_multiline_comments(curly):
|
||||
curly.read_line("namespace Test {")
|
||||
curly.read_line("/*")
|
||||
curly.read_line("}")
|
||||
curly.read_line("*/")
|
||||
assert curly.get_prefix() == "Test"
|
||||
curly.read_line("}")
|
||||
assert curly.get_prefix() == ""
|
||||
|
||||
|
||||
def test_nested(curly):
|
||||
curly.read_line("namespace Test {")
|
||||
curly.read_line("namespace Foo {")
|
||||
assert curly.get_prefix() == "Test::Foo"
|
||||
curly.read_line("}")
|
||||
assert curly.get_prefix() == "Test"
|
||||
|
||||
|
||||
sanitize_cases = [
|
||||
("", ""),
|
||||
(" ", ""),
|
||||
("{", "{"),
|
||||
("// comments {", ""),
|
||||
("{ // why comment here", "{"),
|
||||
("/* comments */ {", "{"),
|
||||
('"curly in a string {"', '""'),
|
||||
('if (!strcmp("hello { there }", g_test)) {', 'if (!strcmp("", g_test)) {'),
|
||||
("'{'", "''"),
|
||||
("weird_function('\"', hello, '\"')", "weird_function('', hello, '')"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("start, end", sanitize_cases)
|
||||
def test_sanitize(start: str, end: str):
|
||||
"""Make sure that we can remove curly braces in places where they should
|
||||
not be considered as part of the semantic structure of the file.
|
||||
i.e. inside strings or chars, and inside comments"""
|
||||
assert sanitize_code_line(start) == end
|
||||
@@ -48,6 +48,7 @@ vtable_cases = [
|
||||
("??_7LegoCarBuildAnimPresenter@@6B@", "LegoCarBuildAnimPresenter"),
|
||||
("??_7?$MxCollection@PAVLegoWorld@@@@6B@", "MxCollection<LegoWorld *>"),
|
||||
("??_7?$MxPtrList@VLegoPathController@@@@6B@", "MxPtrList<LegoPathController>"),
|
||||
("??_7Renderer@Tgl@@6B@", "Tgl::Renderer"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -521,3 +521,111 @@ def test_string_ignore_g_prefix(parser):
|
||||
)
|
||||
assert len(parser.strings) == 1
|
||||
assert len(parser.alerts) == 0
|
||||
|
||||
|
||||
def test_class_variable(parser):
|
||||
"""We should accurately name static variables that are class members."""
|
||||
|
||||
parser.read_lines(
|
||||
[
|
||||
"class Test {",
|
||||
"protected:",
|
||||
" // GLOBAL: TEST 0x1234",
|
||||
" static int g_test;",
|
||||
"};",
|
||||
]
|
||||
)
|
||||
|
||||
assert len(parser.variables) == 1
|
||||
assert parser.variables[0].name == "Test::g_test"
|
||||
|
||||
|
||||
def test_namespace_variable(parser):
|
||||
"""We should identify a namespace surrounding any global variables"""
|
||||
|
||||
parser.read_lines(
|
||||
[
|
||||
"namespace Test {",
|
||||
"// GLOBAL: TEST 0x1234",
|
||||
"int g_test = 1234;",
|
||||
"}",
|
||||
"// GLOBAL: TEST 0x5555",
|
||||
"int g_second = 2;",
|
||||
]
|
||||
)
|
||||
|
||||
assert len(parser.variables) == 2
|
||||
assert parser.variables[0].name == "Test::g_test"
|
||||
assert parser.variables[1].name == "g_second"
|
||||
|
||||
|
||||
def test_namespace_vtable(parser):
|
||||
parser.read_lines(
|
||||
[
|
||||
"namespace Tgl {",
|
||||
"// VTABLE: TEST 0x1234",
|
||||
"class Renderer {",
|
||||
"};",
|
||||
"}",
|
||||
"// VTABLE: TEST 0x5555",
|
||||
"class Hello { };",
|
||||
]
|
||||
)
|
||||
|
||||
assert len(parser.vtables) == 2
|
||||
assert parser.vtables[0].name == "Tgl::Renderer"
|
||||
assert parser.vtables[1].name == "Hello"
|
||||
|
||||
|
||||
def test_global_prefix_namespace(parser):
|
||||
"""Should correctly identify namespaces before checking for the g_ prefix"""
|
||||
|
||||
parser.read_lines(
|
||||
[
|
||||
"class Test {",
|
||||
" // GLOBAL: TEST 0x1234",
|
||||
" static int g_count = 0;",
|
||||
" // GLOBAL: TEST 0x5555",
|
||||
" static int count = 0;",
|
||||
"};",
|
||||
]
|
||||
)
|
||||
|
||||
assert len(parser.variables) == 2
|
||||
assert parser.variables[0].name == "Test::g_count"
|
||||
assert parser.variables[1].name == "Test::count"
|
||||
|
||||
assert len(parser.alerts) == 1
|
||||
assert parser.alerts[0].code == ParserError.GLOBAL_MISSING_PREFIX
|
||||
|
||||
|
||||
def test_nested_namespace(parser):
|
||||
parser.read_lines(
|
||||
[
|
||||
"namespace Tgl {",
|
||||
"class Renderer {",
|
||||
" // GLOBAL: TEST 0x1234",
|
||||
" static int g_count = 0;",
|
||||
"};",
|
||||
"};",
|
||||
]
|
||||
)
|
||||
|
||||
assert len(parser.variables) == 1
|
||||
assert parser.variables[0].name == "Tgl::Renderer::g_count"
|
||||
|
||||
|
||||
def test_match_qualified_variable(parser):
|
||||
"""If a variable belongs to a scope and we use a fully qualified reference
|
||||
below a GLOBAL marker, make sure we capture the full name."""
|
||||
|
||||
parser.read_lines(
|
||||
[
|
||||
"// GLOBAL: TEST 0x1234",
|
||||
"int MxTest::g_count = 0;",
|
||||
]
|
||||
)
|
||||
|
||||
assert len(parser.variables) == 1
|
||||
assert parser.variables[0].name == "MxTest::g_count"
|
||||
assert len(parser.alerts) == 0
|
||||
|
||||
Reference in New Issue
Block a user