Refactor symbolfile script

Introduce the class `Filter` which encapsulates conditions
(architecture, api level, whether llndk is included, etc.) so that we
don't need to touch many places everytime a new condition is added.

In addition, refactor test_symbolfile to reduce duplications

This CL doesn't add a new functionality.

Bug: 239274367
Test: run test_ndkstubgen and test_symbolfile
Change-Id: I188e482492d39ec18134ecc5c908f0d288a754a9
This commit is contained in:
Jiyong Park 2022-07-16 23:30:09 +09:00
parent 70019a90be
commit 3f9c41d2f5
6 changed files with 243 additions and 261 deletions

View file

@ -23,6 +23,7 @@ import sys
from xml.etree.ElementTree import Element, SubElement, tostring
from symbolfile import (
ALL_ARCHITECTURES,
Filter,
FUTURE_API_LEVEL,
MultiplyDefinedSymbolError,
SymbolFileParser,
@ -139,9 +140,8 @@ def main():
with open(args.symbol_file) as symbol_file:
try:
versions = SymbolFileParser(
symbol_file, api_map, "", FUTURE_API_LEVEL, True, True
).parse()
filt = Filter("", FUTURE_API_LEVEL, True, True)
versions = SymbolFileParser(symbol_file, api_map, filt).parse()
except MultiplyDefinedSymbolError as ex:
sys.exit('{}: error: {}'.format(args.symbol_file, ex))

View file

@ -20,7 +20,7 @@ import textwrap
import unittest
from xml.etree.ElementTree import fromstring
from symbolfile import FUTURE_API_LEVEL, SymbolFileParser
from symbolfile import Filter, FUTURE_API_LEVEL, SymbolFileParser
import ndk_api_coverage_parser as nparser
@ -78,9 +78,8 @@ class ApiCoverageSymbolFileParserTest(unittest.TestCase):
"""
)
)
parser = SymbolFileParser(
input_file, {}, "", FUTURE_API_LEVEL, True, True
)
filt = Filter("", FUTURE_API_LEVEL, True, True)
parser = SymbolFileParser(input_file, {}, filt)
generator = nparser.XmlGenerator(io.StringIO())
result = generator.convertToXml(parser.parse())
expected = fromstring(

View file

@ -29,15 +29,12 @@ from symbolfile import Arch, Version
class Generator:
"""Output generator that writes stub source files and version scripts."""
def __init__(self, src_file: TextIO, version_script: TextIO,
symbol_list: TextIO, arch: Arch, api: int, llndk: bool,
apex: bool) -> None:
symbol_list: TextIO, filt: symbolfile.Filter) -> None:
self.src_file = src_file
self.version_script = version_script
self.symbol_list = symbol_list
self.arch = arch
self.api = api
self.llndk = llndk
self.apex = apex
self.filter = filt
self.api = filt.api
def write(self, versions: Iterable[Version]) -> None:
"""Writes all symbol data to the output files."""
@ -47,8 +44,7 @@ class Generator:
def write_version(self, version: Version) -> None:
"""Writes a single version block's data to the output files."""
if symbolfile.should_omit_version(version, self.arch, self.api,
self.llndk, self.apex):
if self.filter.should_omit_version(version):
return
section_versioned = symbolfile.symbol_versioned_in_api(
@ -56,8 +52,7 @@ class Generator:
version_empty = True
pruned_symbols = []
for symbol in version.symbols:
if symbolfile.should_omit_symbol(symbol, self.arch, self.api,
self.llndk, self.apex):
if self.filter.should_omit_symbol(symbol):
continue
if symbolfile.symbol_versioned_in_api(symbol.tags, self.api):
@ -152,11 +147,10 @@ def main() -> None:
verbosity = 2
logging.basicConfig(level=verbose_map[verbosity])
filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex)
with args.symbol_file.open() as symbol_file:
try:
versions = symbolfile.SymbolFileParser(symbol_file, api_map,
args.arch, api, args.llndk,
args.apex).parse()
versions = symbolfile.SymbolFileParser(symbol_file, api_map, filt).parse()
except symbolfile.MultiplyDefinedSymbolError as ex:
sys.exit(f'{args.symbol_file}: error: {ex}')
@ -164,7 +158,7 @@ def main() -> None:
with args.version_script.open('w') as version_script:
with args.symbol_list.open('w') as symbol_list:
generator = Generator(src_file, version_script, symbol_list,
args.arch, api, args.llndk, args.apex)
filt)
generator.write(versions)

View file

@ -18,6 +18,7 @@
import io
import textwrap
import unittest
from copy import copy
import symbolfile
from symbolfile import Arch, Tags
@ -29,6 +30,9 @@ import ndkstubgen
class GeneratorTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
def test_omit_version(self) -> None:
# Thorough testing of the cases involved here is handled by
# OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
@ -37,7 +41,7 @@ class GeneratorTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
version = symbolfile.Version('VERSION_PRIVATE', None, Tags(), [
symbolfile.Symbol('foo', Tags()),
@ -70,7 +74,7 @@ class GeneratorTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
version = symbolfile.Version('VERSION_1', None, Tags(), [
symbolfile.Symbol('foo', Tags.from_strs(['x86'])),
@ -106,7 +110,7 @@ class GeneratorTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
versions = [
symbolfile.Version('VERSION_1', None, Tags(), [
@ -162,6 +166,9 @@ class GeneratorTest(unittest.TestCase):
class IntegrationTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
def test_integration(self) -> None:
api_map = {
'O': 9000,
@ -199,8 +206,7 @@ class IntegrationTest(unittest.TestCase):
wobble;
} VERSION_4;
"""))
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
9, False, False)
parser = symbolfile.SymbolFileParser(input_file, api_map, self.filter)
versions = parser.parse()
src_file = io.StringIO()
@ -208,7 +214,7 @@ class IntegrationTest(unittest.TestCase):
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, False)
self.filter)
generator.write(versions)
expected_src = textwrap.dedent("""\
@ -263,16 +269,18 @@ class IntegrationTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
9001, False, False)
f = copy(self.filter)
f.api = 9001
parser = symbolfile.SymbolFileParser(input_file, api_map, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
f = copy(self.filter)
f.api = 9001
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9001, False, False)
version_file, symbol_list_file, f)
generator.write(versions)
expected_src = textwrap.dedent("""\
@ -322,8 +330,9 @@ class IntegrationTest(unittest.TestCase):
} VERSION_2;
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
f = copy(self.filter)
f.api = 16
parser = symbolfile.SymbolFileParser(input_file, {}, f)
with self.assertRaises(
symbolfile.MultiplyDefinedSymbolError) as ex_context:
@ -370,16 +379,18 @@ class IntegrationTest(unittest.TestCase):
wobble;
} VERSION_4;
"""))
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
9, False, True)
f = copy(self.filter)
f.apex = True
parser = symbolfile.SymbolFileParser(input_file, api_map, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
f = copy(self.filter)
f.apex = True
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
Arch('arm'), 9, False, True)
version_file, symbol_list_file, f)
generator.write(versions)
expected_src = textwrap.dedent("""\
@ -428,20 +439,19 @@ class IntegrationTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
9, llndk=False, apex=True)
f = copy(self.filter)
f.apex = True
parser = symbolfile.SymbolFileParser(input_file, {}, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
f = copy(self.filter)
f.apex = True
generator = ndkstubgen.Generator(src_file,
version_file,
symbol_list_file,
Arch('arm'),
9,
llndk=False,
apex=True)
symbol_list_file, f)
generator.write(versions)
self.assertEqual('', src_file.getvalue())

View file

@ -198,50 +198,55 @@ def get_tag_value(tag: Tag) -> str:
"""
return split_tag(tag)[1]
def _should_omit_tags(tags: Tags, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
"""Returns True if the tagged object should be omitted.
This defines the rules shared between version tagging and symbol tagging.
class Filter:
"""A filter encapsulates a condition that tells whether a version or a
symbol should be omitted or not
"""
# The apex and llndk tags will only exclude APIs from other modes. If in
# APEX or LLNDK mode and neither tag is provided, we fall back to the
# default behavior because all NDK symbols are implicitly available to APEX
# and LLNDK.
if tags.has_mode_tags:
if not apex and not llndk:
def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False):
self.arch = arch
self.api = api
self.llndk = llndk
self.apex = apex
def _should_omit_tags(self, tags: Tags) -> bool:
"""Returns True if the tagged object should be omitted.
This defines the rules shared between version tagging and symbol tagging.
"""
# The apex and llndk tags will only exclude APIs from other modes. If in
# APEX or LLNDK mode and neither tag is provided, we fall back to the
# default behavior because all NDK symbols are implicitly available to
# APEX and LLNDK.
if tags.has_mode_tags:
if not self.apex and not self.llndk:
return True
if self.apex and not tags.has_apex_tags:
return True
if self.llndk and not tags.has_llndk_tags:
return True
if not symbol_in_arch(tags, self.arch):
return True
if apex and not tags.has_apex_tags:
if not symbol_in_api(tags, self.arch, self.api):
return True
if llndk and not tags.has_llndk_tags:
return False
def should_omit_version(self, version: Version) -> bool:
"""Returns True if the version section should be omitted.
We want to omit any sections that do not have any symbols we'll have in
the stub library. Sections that contain entirely future symbols or only
symbols for certain architectures.
"""
if version.is_private:
return True
if not symbol_in_arch(tags, arch):
return True
if not symbol_in_api(tags, arch, api):
return True
return False
if version.tags.has_platform_only_tags:
return True
return self._should_omit_tags(version.tags)
def should_omit_version(version: Version, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
"""Returns True if the version section should be omitted.
We want to omit any sections that do not have any symbols we'll have in the
stub library. Sections that contain entirely future symbols or only symbols
for certain architectures.
"""
if version.is_private:
return True
if version.tags.has_platform_only_tags:
return True
return _should_omit_tags(version.tags, arch, api, llndk, apex)
def should_omit_symbol(symbol: Symbol, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
"""Returns True if the symbol should be omitted."""
return _should_omit_tags(symbol.tags, arch, api, llndk, apex)
def should_omit_symbol(self, symbol: Symbol) -> bool:
"""Returns True if the symbol should be omitted."""
return self._should_omit_tags(symbol.tags)
def symbol_in_arch(tags: Tags, arch: Arch) -> bool:
@ -316,14 +321,10 @@ class MultiplyDefinedSymbolError(RuntimeError):
class SymbolFileParser:
"""Parses NDK symbol files."""
def __init__(self, input_file: TextIO, api_map: ApiMap, arch: Arch,
api: int, llndk: bool, apex: bool) -> None:
def __init__(self, input_file: TextIO, api_map: ApiMap, filt: Filter) -> None:
self.input_file = input_file
self.api_map = api_map
self.arch = arch
self.api = api
self.llndk = llndk
self.apex = apex
self.filter = filt
self.current_line: Optional[str] = None
def parse(self) -> List[Version]:
@ -352,13 +353,11 @@ class SymbolFileParser:
symbol_names = set()
multiply_defined_symbols = set()
for version in versions:
if should_omit_version(version, self.arch, self.api, self.llndk,
self.apex):
if self.filter.should_omit_version(version):
continue
for symbol in version.symbols:
if should_omit_symbol(symbol, self.arch, self.api, self.llndk,
self.apex):
if self.filter.should_omit_symbol(symbol):
continue
if symbol.name in symbol_names:

View file

@ -19,7 +19,8 @@ import textwrap
import unittest
import symbolfile
from symbolfile import Arch, Tag, Tags, Version
from symbolfile import Arch, Tag, Tags, Version, Symbol, Filter
from copy import copy
# pylint: disable=missing-docstring
@ -202,178 +203,166 @@ class SymbolPresenceTest(unittest.TestCase):
class OmitVersionTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = Filter(arch = Arch('arm'), api = 9)
self.version = Version('foo', None, Tags(), [])
def assertOmit(self, f: Filter, v: Version) -> None:
self.assertTrue(f.should_omit_version(v))
def assertInclude(self, f: Filter, v: Version) -> None:
self.assertFalse(f.should_omit_version(v))
def test_omit_private(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, False))
f = self.filter
v = self.version
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo_PRIVATE', None, Tags(), []),
Arch('arm'), 9, False, False))
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo_PLATFORM', None, Tags(), []),
Arch('arm'), 9, False, False))
self.assertInclude(f, v)
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None,
Tags.from_strs(['platform-only']), []),
Arch('arm'), 9, False, False))
v.name = 'foo_PRIVATE'
self.assertOmit(f, v)
v.name = 'foo_PLATFORM'
self.assertOmit(f, v)
v.name = 'foo'
v.tags = Tags.from_strs(['platform-only'])
self.assertOmit(f, v)
def test_omit_llndk(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Arch('arm'), 9, False, False))
f = self.filter
v = self.version
v_llndk = copy(v)
v_llndk.tags = Tags.from_strs(['llndk'])
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
True, False))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Arch('arm'), 9, True, False))
self.assertOmit(f, v_llndk)
f.llndk = True
self.assertInclude(f, v)
self.assertInclude(f, v_llndk)
def test_omit_apex(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Arch('arm'), 9, False, False))
f = self.filter
v = self.version
v_apex = copy(v)
v_apex.tags = Tags.from_strs(['apex'])
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, True))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Arch('arm'), 9, False, True))
self.assertOmit(f, v_apex)
f.apex = True
self.assertInclude(f, v)
self.assertInclude(f, v_apex)
def test_omit_systemapi(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
[]), Arch('arm'), 9, False, False))
f = self.filter
v = self.version
v_systemapi = copy(v)
v_systemapi.tags = Tags.from_strs(['systemapi'])
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, True))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
[]), Arch('arm'), 9, False, True))
self.assertOmit(f, v_systemapi)
f.apex = True
self.assertInclude(f, v)
self.assertInclude(f, v_systemapi)
def test_omit_arch(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, False))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['arm']), []),
Arch('arm'), 9, False, False))
f_arm = self.filter
v_none = self.version
self.assertInclude(f_arm, v_none)
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags.from_strs(['x86']), []),
Arch('arm'), 9, False, False))
v_arm = copy(v_none)
v_arm.tags = Tags.from_strs(['arm'])
self.assertInclude(f_arm, v_arm)
v_x86 = copy(v_none)
v_x86.tags = Tags.from_strs(['x86'])
self.assertOmit(f_arm, v_x86)
def test_omit_api(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
False, False))
self.assertFalse(
symbolfile.should_omit_version(
symbolfile.Version('foo', None,
Tags.from_strs(['introduced=9']), []),
Arch('arm'), 9, False, False))
f_api9 = self.filter
v_none = self.version
self.assertInclude(f_api9, v_none)
self.assertTrue(
symbolfile.should_omit_version(
symbolfile.Version('foo', None,
Tags.from_strs(['introduced=14']), []),
Arch('arm'), 9, False, False))
v_api9 = copy(v_none)
v_api9.tags = Tags.from_strs(['introduced=9'])
self.assertInclude(f_api9, v_api9)
v_api14 = copy(v_none)
v_api14.tags = Tags.from_strs(['introduced=14'])
self.assertOmit(f_api9, v_api14)
class OmitSymbolTest(unittest.TestCase):
def test_omit_llndk(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
Arch('arm'), 9, False, False))
def setUp(self) -> None:
self.filter = Filter(arch = Arch('arm'), api = 9)
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, True, False))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
Arch('arm'), 9, True, False))
def assertOmit(self, f: Filter, s: Symbol) -> None:
self.assertTrue(f.should_omit_symbol(s))
def assertInclude(self, f: Filter, s: Symbol) -> None:
self.assertFalse(f.should_omit_symbol(s))
def test_omit_llndk(self) -> None:
f_none = self.filter
f_llndk = copy(f_none)
f_llndk.llndk = True
s_none = Symbol('foo', Tags())
s_llndk = Symbol('foo', Tags.from_strs(['llndk']))
self.assertOmit(f_none, s_llndk)
self.assertInclude(f_llndk, s_none)
self.assertInclude(f_llndk, s_llndk)
def test_omit_apex(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
Arch('arm'), 9, False, False))
f_none = self.filter
f_apex = copy(f_none)
f_apex.apex = True
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, True))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
Arch('arm'), 9, False, True))
s_none = Symbol('foo', Tags())
s_apex = Symbol('foo', Tags.from_strs(['apex']))
self.assertOmit(f_none, s_apex)
self.assertInclude(f_apex, s_none)
self.assertInclude(f_apex, s_apex)
def test_omit_systemapi(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
Arch('arm'), 9, False, False))
f_none = self.filter
f_systemapi = copy(f_none)
f_systemapi.apex = True
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, True))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
Arch('arm'), 9, False, True))
s_none = Symbol('foo', Tags())
s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
self.assertOmit(f_none, s_systemapi)
self.assertInclude(f_systemapi, s_none)
self.assertInclude(f_systemapi, s_systemapi)
def test_omit_arch(self) -> None:
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['arm'])), Arch('arm'),
9, False, False))
f_arm = self.filter
s_none = Symbol('foo', Tags())
s_arm = Symbol('foo', Tags.from_strs(['arm']))
s_x86 = Symbol('foo', Tags.from_strs(['x86']))
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['x86'])), Arch('arm'),
9, False, False))
self.assertInclude(f_arm, s_none)
self.assertInclude(f_arm, s_arm)
self.assertOmit(f_arm, s_x86)
def test_omit_api(self) -> None:
self.assertFalse(
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['introduced=9'])),
Arch('arm'), 9, False, False))
f_api9 = self.filter
s_none = Symbol('foo', Tags())
s_api9 = Symbol('foo', Tags.from_strs(['introduced=9']))
s_api14 = Symbol('foo', Tags.from_strs(['introduced=14']))
self.assertTrue(
symbolfile.should_omit_symbol(
symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])),
Arch('arm'), 9, False, False))
self.assertInclude(f_api9, s_none)
self.assertInclude(f_api9, s_api9)
self.assertOmit(f_api9, s_api14)
class SymbolFileParseTest(unittest.TestCase):
def setUp(self) -> None:
self.filter = Filter(arch = Arch('arm'), api = 16)
def test_next_line(self) -> None:
input_file = io.StringIO(textwrap.dedent("""\
foo
@ -382,8 +371,7 @@ class SymbolFileParseTest(unittest.TestCase):
# baz
qux
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
self.assertIsNone(parser.current_line)
self.assertEqual('foo', parser.next_line().strip())
@ -409,8 +397,7 @@ class SymbolFileParseTest(unittest.TestCase):
VERSION_2 {
} VERSION_1; # asdf
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
version = parser.parse_version()
@ -419,8 +406,8 @@ class SymbolFileParseTest(unittest.TestCase):
self.assertEqual(Tags.from_strs(['foo', 'bar']), version.tags)
expected_symbols = [
symbolfile.Symbol('baz', Tags()),
symbolfile.Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
Symbol('baz', Tags()),
Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
]
self.assertEqual(expected_symbols, version.symbols)
@ -434,8 +421,7 @@ class SymbolFileParseTest(unittest.TestCase):
input_file = io.StringIO(textwrap.dedent("""\
VERSION_1 {
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@ -446,8 +432,7 @@ class SymbolFileParseTest(unittest.TestCase):
foo:
}
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@ -457,8 +442,7 @@ class SymbolFileParseTest(unittest.TestCase):
foo;
bar; # baz qux
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
symbol = parser.parse_symbol()
@ -476,8 +460,7 @@ class SymbolFileParseTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@ -489,8 +472,7 @@ class SymbolFileParseTest(unittest.TestCase):
*;
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
version = parser.parse_version()
self.assertEqual([], version.symbols)
@ -501,8 +483,7 @@ class SymbolFileParseTest(unittest.TestCase):
foo
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@ -510,8 +491,7 @@ class SymbolFileParseTest(unittest.TestCase):
def test_parse_fails_invalid_input(self) -> None:
with self.assertRaises(symbolfile.ParseError):
input_file = io.StringIO('foo')
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
16, False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.parse()
def test_parse(self) -> None:
@ -532,19 +512,18 @@ class SymbolFileParseTest(unittest.TestCase):
qwerty;
} VERSION_1;
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, False)
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
versions = parser.parse()
expected = [
symbolfile.Version('VERSION_1', None, Tags(), [
symbolfile.Symbol('foo', Tags()),
symbolfile.Symbol('bar', Tags.from_strs(['baz'])),
Symbol('foo', Tags()),
Symbol('bar', Tags.from_strs(['baz'])),
]),
symbolfile.Version(
'VERSION_2', 'VERSION_1', Tags.from_strs(['wasd']), [
symbolfile.Symbol('woodly', Tags()),
symbolfile.Symbol('doodly', Tags.from_strs(['asdf'])),
Symbol('woodly', Tags()),
Symbol('doodly', Tags.from_strs(['asdf'])),
]),
]
@ -559,8 +538,9 @@ class SymbolFileParseTest(unittest.TestCase):
qux; # apex
};
"""))
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
False, True)
f = copy(self.filter)
f.llndk = True
parser = symbolfile.SymbolFileParser(input_file, {}, f)
parser.next_line()
version = parser.parse_version()
@ -568,10 +548,10 @@ class SymbolFileParseTest(unittest.TestCase):
self.assertIsNone(version.base)
expected_symbols = [
symbolfile.Symbol('foo', Tags()),
symbolfile.Symbol('bar', Tags.from_strs(['llndk'])),
symbolfile.Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
symbolfile.Symbol('qux', Tags.from_strs(['apex'])),
Symbol('foo', Tags()),
Symbol('bar', Tags.from_strs(['llndk'])),
Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
Symbol('qux', Tags.from_strs(['apex'])),
]
self.assertEqual(expected_symbols, version.symbols)