Merge changes I0484ea34,I188e4824 am: b3f18a9f9f
am: 03c590b4e1
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2153678 Change-Id: I385312a0ff3627c4370a4dfc4de9586718ac6078 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -949,8 +949,10 @@ func TestApexWithStubs(t *testing.T) {
|
|||||||
// mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
|
// mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
|
||||||
// ensureNotContains(t, mylib2Cflags, "-include ")
|
// ensureNotContains(t, mylib2Cflags, "-include ")
|
||||||
|
|
||||||
// Ensure that genstub is invoked with --apex
|
// Ensure that genstub for platform-provided lib is invoked with --systemapi
|
||||||
ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"])
|
ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
|
||||||
|
// Ensure that genstub for apex-provided lib is invoked with --apex
|
||||||
|
ensureContains(t, ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
|
||||||
|
|
||||||
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
||||||
"lib64/mylib.so",
|
"lib64/mylib.so",
|
||||||
@@ -1134,8 +1136,8 @@ func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
|
|||||||
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
|
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
|
||||||
ensureNotContains(t, mylib2Cflags, "-include ")
|
ensureNotContains(t, mylib2Cflags, "-include ")
|
||||||
|
|
||||||
// Ensure that genstub is invoked with --apex
|
// Ensure that genstub is invoked with --systemapi
|
||||||
ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"])
|
ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi")
|
||||||
|
|
||||||
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
||||||
"lib64/mylib.so",
|
"lib64/mylib.so",
|
||||||
|
@@ -1032,9 +1032,19 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
|
|||||||
ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
|
ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
|
||||||
return Objects{}
|
return Objects{}
|
||||||
}
|
}
|
||||||
|
// b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
|
||||||
|
// systemapi, respectively. The former is for symbols defined in platform libraries
|
||||||
|
// and the latter is for symbols defined in APEXes.
|
||||||
|
var flag string
|
||||||
|
if ctx.Module().(android.ApexModule).NotInPlatform() {
|
||||||
|
flag = "--apex"
|
||||||
|
} else {
|
||||||
|
// TODO(b/239274367) drop --apex when #apex is replaced with #systemapi
|
||||||
|
// in the map.txt files of platform libraries
|
||||||
|
flag = "--systemapi --apex"
|
||||||
|
}
|
||||||
nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
|
nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
|
||||||
android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion),
|
android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
|
||||||
"--apex")
|
|
||||||
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
|
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
|
||||||
library.versionScriptPath = android.OptionalPathForPath(
|
library.versionScriptPath = android.OptionalPathForPath(
|
||||||
nativeAbiResult.versionScript)
|
nativeAbiResult.versionScript)
|
||||||
|
@@ -23,6 +23,7 @@ import sys
|
|||||||
from xml.etree.ElementTree import Element, SubElement, tostring
|
from xml.etree.ElementTree import Element, SubElement, tostring
|
||||||
from symbolfile import (
|
from symbolfile import (
|
||||||
ALL_ARCHITECTURES,
|
ALL_ARCHITECTURES,
|
||||||
|
Filter,
|
||||||
FUTURE_API_LEVEL,
|
FUTURE_API_LEVEL,
|
||||||
MultiplyDefinedSymbolError,
|
MultiplyDefinedSymbolError,
|
||||||
SymbolFileParser,
|
SymbolFileParser,
|
||||||
@@ -139,9 +140,8 @@ def main():
|
|||||||
|
|
||||||
with open(args.symbol_file) as symbol_file:
|
with open(args.symbol_file) as symbol_file:
|
||||||
try:
|
try:
|
||||||
versions = SymbolFileParser(
|
filt = Filter("", FUTURE_API_LEVEL, True, True, True)
|
||||||
symbol_file, api_map, "", FUTURE_API_LEVEL, True, True
|
versions = SymbolFileParser(symbol_file, api_map, filt).parse()
|
||||||
).parse()
|
|
||||||
except MultiplyDefinedSymbolError as ex:
|
except MultiplyDefinedSymbolError as ex:
|
||||||
sys.exit('{}: error: {}'.format(args.symbol_file, ex))
|
sys.exit('{}: error: {}'.format(args.symbol_file, ex))
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ import textwrap
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from xml.etree.ElementTree import fromstring
|
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
|
import ndk_api_coverage_parser as nparser
|
||||||
|
|
||||||
|
|
||||||
@@ -78,9 +78,8 @@ class ApiCoverageSymbolFileParserTest(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
parser = SymbolFileParser(
|
filt = Filter("", FUTURE_API_LEVEL, True, True, True)
|
||||||
input_file, {}, "", FUTURE_API_LEVEL, True, True
|
parser = SymbolFileParser(input_file, {}, filt)
|
||||||
)
|
|
||||||
generator = nparser.XmlGenerator(io.StringIO())
|
generator = nparser.XmlGenerator(io.StringIO())
|
||||||
result = generator.convertToXml(parser.parse())
|
result = generator.convertToXml(parser.parse())
|
||||||
expected = fromstring(
|
expected = fromstring(
|
||||||
|
@@ -29,15 +29,12 @@ from symbolfile import Arch, Version
|
|||||||
class Generator:
|
class Generator:
|
||||||
"""Output generator that writes stub source files and version scripts."""
|
"""Output generator that writes stub source files and version scripts."""
|
||||||
def __init__(self, src_file: TextIO, version_script: TextIO,
|
def __init__(self, src_file: TextIO, version_script: TextIO,
|
||||||
symbol_list: TextIO, arch: Arch, api: int, llndk: bool,
|
symbol_list: TextIO, filt: symbolfile.Filter) -> None:
|
||||||
apex: bool) -> None:
|
|
||||||
self.src_file = src_file
|
self.src_file = src_file
|
||||||
self.version_script = version_script
|
self.version_script = version_script
|
||||||
self.symbol_list = symbol_list
|
self.symbol_list = symbol_list
|
||||||
self.arch = arch
|
self.filter = filt
|
||||||
self.api = api
|
self.api = filt.api
|
||||||
self.llndk = llndk
|
|
||||||
self.apex = apex
|
|
||||||
|
|
||||||
def write(self, versions: Iterable[Version]) -> None:
|
def write(self, versions: Iterable[Version]) -> None:
|
||||||
"""Writes all symbol data to the output files."""
|
"""Writes all symbol data to the output files."""
|
||||||
@@ -47,8 +44,7 @@ class Generator:
|
|||||||
|
|
||||||
def write_version(self, version: Version) -> None:
|
def write_version(self, version: Version) -> None:
|
||||||
"""Writes a single version block's data to the output files."""
|
"""Writes a single version block's data to the output files."""
|
||||||
if symbolfile.should_omit_version(version, self.arch, self.api,
|
if self.filter.should_omit_version(version):
|
||||||
self.llndk, self.apex):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
section_versioned = symbolfile.symbol_versioned_in_api(
|
section_versioned = symbolfile.symbol_versioned_in_api(
|
||||||
@@ -56,8 +52,7 @@ class Generator:
|
|||||||
version_empty = True
|
version_empty = True
|
||||||
pruned_symbols = []
|
pruned_symbols = []
|
||||||
for symbol in version.symbols:
|
for symbol in version.symbols:
|
||||||
if symbolfile.should_omit_symbol(symbol, self.arch, self.api,
|
if self.filter.should_omit_symbol(symbol):
|
||||||
self.llndk, self.apex):
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if symbolfile.symbol_versioned_in_api(symbol.tags, self.api):
|
if symbolfile.symbol_versioned_in_api(symbol.tags, self.api):
|
||||||
@@ -110,12 +105,12 @@ def parse_args() -> argparse.Namespace:
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--apex',
|
'--apex',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Use the APEX variant. Note: equivalent to --system-api.')
|
help='Use the APEX variant.')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--system-api',
|
'--systemapi',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='apex',
|
dest='systemapi',
|
||||||
help='Use the SystemAPI variant. Note: equivalent to --apex.')
|
help='Use the SystemAPI variant.')
|
||||||
|
|
||||||
parser.add_argument('--api-map',
|
parser.add_argument('--api-map',
|
||||||
type=resolved_path,
|
type=resolved_path,
|
||||||
@@ -152,11 +147,10 @@ def main() -> None:
|
|||||||
verbosity = 2
|
verbosity = 2
|
||||||
logging.basicConfig(level=verbose_map[verbosity])
|
logging.basicConfig(level=verbose_map[verbosity])
|
||||||
|
|
||||||
|
filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex, args.systemapi)
|
||||||
with args.symbol_file.open() as symbol_file:
|
with args.symbol_file.open() as symbol_file:
|
||||||
try:
|
try:
|
||||||
versions = symbolfile.SymbolFileParser(symbol_file, api_map,
|
versions = symbolfile.SymbolFileParser(symbol_file, api_map, filt).parse()
|
||||||
args.arch, api, args.llndk,
|
|
||||||
args.apex).parse()
|
|
||||||
except symbolfile.MultiplyDefinedSymbolError as ex:
|
except symbolfile.MultiplyDefinedSymbolError as ex:
|
||||||
sys.exit(f'{args.symbol_file}: error: {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.version_script.open('w') as version_script:
|
||||||
with args.symbol_list.open('w') as symbol_list:
|
with args.symbol_list.open('w') as symbol_list:
|
||||||
generator = Generator(src_file, version_script, symbol_list,
|
generator = Generator(src_file, version_script, symbol_list,
|
||||||
args.arch, api, args.llndk, args.apex)
|
filt)
|
||||||
generator.write(versions)
|
generator.write(versions)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
import io
|
import io
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
import symbolfile
|
import symbolfile
|
||||||
from symbolfile import Arch, Tags
|
from symbolfile import Arch, Tags
|
||||||
@@ -29,6 +30,9 @@ import ndkstubgen
|
|||||||
|
|
||||||
|
|
||||||
class GeneratorTest(unittest.TestCase):
|
class GeneratorTest(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
|
||||||
|
|
||||||
def test_omit_version(self) -> None:
|
def test_omit_version(self) -> None:
|
||||||
# Thorough testing of the cases involved here is handled by
|
# Thorough testing of the cases involved here is handled by
|
||||||
# OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
|
# OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
|
||||||
@@ -37,7 +41,7 @@ class GeneratorTest(unittest.TestCase):
|
|||||||
symbol_list_file = io.StringIO()
|
symbol_list_file = io.StringIO()
|
||||||
generator = ndkstubgen.Generator(src_file,
|
generator = ndkstubgen.Generator(src_file,
|
||||||
version_file, symbol_list_file,
|
version_file, symbol_list_file,
|
||||||
Arch('arm'), 9, False, False)
|
self.filter)
|
||||||
|
|
||||||
version = symbolfile.Version('VERSION_PRIVATE', None, Tags(), [
|
version = symbolfile.Version('VERSION_PRIVATE', None, Tags(), [
|
||||||
symbolfile.Symbol('foo', Tags()),
|
symbolfile.Symbol('foo', Tags()),
|
||||||
@@ -70,7 +74,7 @@ class GeneratorTest(unittest.TestCase):
|
|||||||
symbol_list_file = io.StringIO()
|
symbol_list_file = io.StringIO()
|
||||||
generator = ndkstubgen.Generator(src_file,
|
generator = ndkstubgen.Generator(src_file,
|
||||||
version_file, symbol_list_file,
|
version_file, symbol_list_file,
|
||||||
Arch('arm'), 9, False, False)
|
self.filter)
|
||||||
|
|
||||||
version = symbolfile.Version('VERSION_1', None, Tags(), [
|
version = symbolfile.Version('VERSION_1', None, Tags(), [
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['x86'])),
|
symbolfile.Symbol('foo', Tags.from_strs(['x86'])),
|
||||||
@@ -106,7 +110,7 @@ class GeneratorTest(unittest.TestCase):
|
|||||||
symbol_list_file = io.StringIO()
|
symbol_list_file = io.StringIO()
|
||||||
generator = ndkstubgen.Generator(src_file,
|
generator = ndkstubgen.Generator(src_file,
|
||||||
version_file, symbol_list_file,
|
version_file, symbol_list_file,
|
||||||
Arch('arm'), 9, False, False)
|
self.filter)
|
||||||
|
|
||||||
versions = [
|
versions = [
|
||||||
symbolfile.Version('VERSION_1', None, Tags(), [
|
symbolfile.Version('VERSION_1', None, Tags(), [
|
||||||
@@ -162,6 +166,9 @@ class GeneratorTest(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class IntegrationTest(unittest.TestCase):
|
class IntegrationTest(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
|
||||||
|
|
||||||
def test_integration(self) -> None:
|
def test_integration(self) -> None:
|
||||||
api_map = {
|
api_map = {
|
||||||
'O': 9000,
|
'O': 9000,
|
||||||
@@ -199,8 +206,7 @@ class IntegrationTest(unittest.TestCase):
|
|||||||
wobble;
|
wobble;
|
||||||
} VERSION_4;
|
} VERSION_4;
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
|
parser = symbolfile.SymbolFileParser(input_file, api_map, self.filter)
|
||||||
9, False, False)
|
|
||||||
versions = parser.parse()
|
versions = parser.parse()
|
||||||
|
|
||||||
src_file = io.StringIO()
|
src_file = io.StringIO()
|
||||||
@@ -208,7 +214,7 @@ class IntegrationTest(unittest.TestCase):
|
|||||||
symbol_list_file = io.StringIO()
|
symbol_list_file = io.StringIO()
|
||||||
generator = ndkstubgen.Generator(src_file,
|
generator = ndkstubgen.Generator(src_file,
|
||||||
version_file, symbol_list_file,
|
version_file, symbol_list_file,
|
||||||
Arch('arm'), 9, False, False)
|
self.filter)
|
||||||
generator.write(versions)
|
generator.write(versions)
|
||||||
|
|
||||||
expected_src = textwrap.dedent("""\
|
expected_src = textwrap.dedent("""\
|
||||||
@@ -263,16 +269,18 @@ class IntegrationTest(unittest.TestCase):
|
|||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
|
f = copy(self.filter)
|
||||||
9001, False, False)
|
f.api = 9001
|
||||||
|
parser = symbolfile.SymbolFileParser(input_file, api_map, f)
|
||||||
versions = parser.parse()
|
versions = parser.parse()
|
||||||
|
|
||||||
src_file = io.StringIO()
|
src_file = io.StringIO()
|
||||||
version_file = io.StringIO()
|
version_file = io.StringIO()
|
||||||
symbol_list_file = io.StringIO()
|
symbol_list_file = io.StringIO()
|
||||||
|
f = copy(self.filter)
|
||||||
|
f.api = 9001
|
||||||
generator = ndkstubgen.Generator(src_file,
|
generator = ndkstubgen.Generator(src_file,
|
||||||
version_file, symbol_list_file,
|
version_file, symbol_list_file, f)
|
||||||
Arch('arm'), 9001, False, False)
|
|
||||||
generator.write(versions)
|
generator.write(versions)
|
||||||
|
|
||||||
expected_src = textwrap.dedent("""\
|
expected_src = textwrap.dedent("""\
|
||||||
@@ -322,8 +330,9 @@ class IntegrationTest(unittest.TestCase):
|
|||||||
} VERSION_2;
|
} VERSION_2;
|
||||||
|
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
f = copy(self.filter)
|
||||||
False, False)
|
f.api = 16
|
||||||
|
parser = symbolfile.SymbolFileParser(input_file, {}, f)
|
||||||
|
|
||||||
with self.assertRaises(
|
with self.assertRaises(
|
||||||
symbolfile.MultiplyDefinedSymbolError) as ex_context:
|
symbolfile.MultiplyDefinedSymbolError) as ex_context:
|
||||||
@@ -370,16 +379,18 @@ class IntegrationTest(unittest.TestCase):
|
|||||||
wobble;
|
wobble;
|
||||||
} VERSION_4;
|
} VERSION_4;
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
|
f = copy(self.filter)
|
||||||
9, False, True)
|
f.apex = True
|
||||||
|
parser = symbolfile.SymbolFileParser(input_file, api_map, f)
|
||||||
versions = parser.parse()
|
versions = parser.parse()
|
||||||
|
|
||||||
src_file = io.StringIO()
|
src_file = io.StringIO()
|
||||||
version_file = io.StringIO()
|
version_file = io.StringIO()
|
||||||
symbol_list_file = io.StringIO()
|
symbol_list_file = io.StringIO()
|
||||||
|
f = copy(self.filter)
|
||||||
|
f.apex = True
|
||||||
generator = ndkstubgen.Generator(src_file,
|
generator = ndkstubgen.Generator(src_file,
|
||||||
version_file, symbol_list_file,
|
version_file, symbol_list_file, f)
|
||||||
Arch('arm'), 9, False, True)
|
|
||||||
generator.write(versions)
|
generator.write(versions)
|
||||||
|
|
||||||
expected_src = textwrap.dedent("""\
|
expected_src = textwrap.dedent("""\
|
||||||
@@ -428,20 +439,19 @@ class IntegrationTest(unittest.TestCase):
|
|||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
|
f = copy(self.filter)
|
||||||
9, llndk=False, apex=True)
|
f.apex = True
|
||||||
|
parser = symbolfile.SymbolFileParser(input_file, {}, f)
|
||||||
versions = parser.parse()
|
versions = parser.parse()
|
||||||
|
|
||||||
src_file = io.StringIO()
|
src_file = io.StringIO()
|
||||||
version_file = io.StringIO()
|
version_file = io.StringIO()
|
||||||
symbol_list_file = io.StringIO()
|
symbol_list_file = io.StringIO()
|
||||||
|
f = copy(self.filter)
|
||||||
|
f.apex = True
|
||||||
generator = ndkstubgen.Generator(src_file,
|
generator = ndkstubgen.Generator(src_file,
|
||||||
version_file,
|
version_file,
|
||||||
symbol_list_file,
|
symbol_list_file, f)
|
||||||
Arch('arm'),
|
|
||||||
9,
|
|
||||||
llndk=False,
|
|
||||||
apex=True)
|
|
||||||
generator.write(versions)
|
generator.write(versions)
|
||||||
|
|
||||||
self.assertEqual('', src_file.getvalue())
|
self.assertEqual('', src_file.getvalue())
|
||||||
|
@@ -78,12 +78,17 @@ class Tags:
|
|||||||
@property
|
@property
|
||||||
def has_mode_tags(self) -> bool:
|
def has_mode_tags(self) -> bool:
|
||||||
"""Returns True if any mode tags (apex, llndk, etc) are set."""
|
"""Returns True if any mode tags (apex, llndk, etc) are set."""
|
||||||
return self.has_apex_tags or self.has_llndk_tags
|
return self.has_apex_tags or self.has_llndk_tags or self.has_systemapi_tags
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_apex_tags(self) -> bool:
|
def has_apex_tags(self) -> bool:
|
||||||
"""Returns True if any APEX tags are set."""
|
"""Returns True if any APEX tags are set."""
|
||||||
return 'apex' in self.tags or 'systemapi' in self.tags
|
return 'apex' in self.tags
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_systemapi_tags(self) -> bool:
|
||||||
|
"""Returns True if any APEX tags are set."""
|
||||||
|
return 'systemapi' in self.tags
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_llndk_tags(self) -> bool:
|
def has_llndk_tags(self) -> bool:
|
||||||
@@ -198,50 +203,57 @@ def get_tag_value(tag: Tag) -> str:
|
|||||||
"""
|
"""
|
||||||
return split_tag(tag)[1]
|
return split_tag(tag)[1]
|
||||||
|
|
||||||
|
class Filter:
|
||||||
def _should_omit_tags(tags: Tags, arch: Arch, api: int, llndk: bool,
|
"""A filter encapsulates a condition that tells whether a version or a
|
||||||
apex: bool) -> bool:
|
symbol should be omitted or not
|
||||||
"""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
|
def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False, systemapi: bool = False):
|
||||||
# default behavior because all NDK symbols are implicitly available to APEX
|
self.arch = arch
|
||||||
# and LLNDK.
|
self.api = api
|
||||||
if tags.has_mode_tags:
|
self.llndk = llndk
|
||||||
if not apex and not llndk:
|
self.apex = apex
|
||||||
|
self.systemapi = systemapi
|
||||||
|
|
||||||
|
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 self.apex and tags.has_apex_tags:
|
||||||
|
return False
|
||||||
|
if self.llndk and tags.has_llndk_tags:
|
||||||
|
return False
|
||||||
|
if self.systemapi and tags.has_systemapi_tags:
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
if apex and not tags.has_apex_tags:
|
if not symbol_in_arch(tags, self.arch):
|
||||||
return True
|
return True
|
||||||
if llndk and not tags.has_llndk_tags:
|
if not symbol_in_api(tags, self.arch, self.api):
|
||||||
return True
|
return True
|
||||||
if not symbol_in_arch(tags, arch):
|
return False
|
||||||
return True
|
|
||||||
if not symbol_in_api(tags, arch, api):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
def should_omit_version(self, version: Version) -> bool:
|
||||||
|
"""Returns True if the version section should be omitted.
|
||||||
|
|
||||||
def should_omit_version(version: Version, arch: Arch, api: int, llndk: bool,
|
We want to omit any sections that do not have any symbols we'll have in
|
||||||
apex: bool) -> bool:
|
the stub library. Sections that contain entirely future symbols or only
|
||||||
"""Returns True if the version section should be omitted.
|
symbols for certain architectures.
|
||||||
|
"""
|
||||||
|
if version.is_private:
|
||||||
|
return True
|
||||||
|
if version.tags.has_platform_only_tags:
|
||||||
|
return True
|
||||||
|
return self._should_omit_tags(version.tags)
|
||||||
|
|
||||||
We want to omit any sections that do not have any symbols we'll have in the
|
def should_omit_symbol(self, symbol: Symbol) -> bool:
|
||||||
stub library. Sections that contain entirely future symbols or only symbols
|
"""Returns True if the symbol should be omitted."""
|
||||||
for certain architectures.
|
return self._should_omit_tags(symbol.tags)
|
||||||
"""
|
|
||||||
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 symbol_in_arch(tags: Tags, arch: Arch) -> bool:
|
def symbol_in_arch(tags: Tags, arch: Arch) -> bool:
|
||||||
@@ -316,14 +328,10 @@ class MultiplyDefinedSymbolError(RuntimeError):
|
|||||||
|
|
||||||
class SymbolFileParser:
|
class SymbolFileParser:
|
||||||
"""Parses NDK symbol files."""
|
"""Parses NDK symbol files."""
|
||||||
def __init__(self, input_file: TextIO, api_map: ApiMap, arch: Arch,
|
def __init__(self, input_file: TextIO, api_map: ApiMap, filt: Filter) -> None:
|
||||||
api: int, llndk: bool, apex: bool) -> None:
|
|
||||||
self.input_file = input_file
|
self.input_file = input_file
|
||||||
self.api_map = api_map
|
self.api_map = api_map
|
||||||
self.arch = arch
|
self.filter = filt
|
||||||
self.api = api
|
|
||||||
self.llndk = llndk
|
|
||||||
self.apex = apex
|
|
||||||
self.current_line: Optional[str] = None
|
self.current_line: Optional[str] = None
|
||||||
|
|
||||||
def parse(self) -> List[Version]:
|
def parse(self) -> List[Version]:
|
||||||
@@ -352,13 +360,11 @@ class SymbolFileParser:
|
|||||||
symbol_names = set()
|
symbol_names = set()
|
||||||
multiply_defined_symbols = set()
|
multiply_defined_symbols = set()
|
||||||
for version in versions:
|
for version in versions:
|
||||||
if should_omit_version(version, self.arch, self.api, self.llndk,
|
if self.filter.should_omit_version(version):
|
||||||
self.apex):
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for symbol in version.symbols:
|
for symbol in version.symbols:
|
||||||
if should_omit_symbol(symbol, self.arch, self.api, self.llndk,
|
if self.filter.should_omit_symbol(symbol):
|
||||||
self.apex):
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if symbol.name in symbol_names:
|
if symbol.name in symbol_names:
|
||||||
|
@@ -19,7 +19,8 @@ import textwrap
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import symbolfile
|
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
|
# pylint: disable=missing-docstring
|
||||||
|
|
||||||
@@ -202,178 +203,188 @@ class SymbolPresenceTest(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class OmitVersionTest(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:
|
def test_omit_private(self) -> None:
|
||||||
self.assertFalse(
|
f = self.filter
|
||||||
symbolfile.should_omit_version(
|
v = self.version
|
||||||
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
|
|
||||||
False, False))
|
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertInclude(f, v)
|
||||||
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.assertTrue(
|
v.name = 'foo_PRIVATE'
|
||||||
symbolfile.should_omit_version(
|
self.assertOmit(f, v)
|
||||||
symbolfile.Version('foo', None,
|
|
||||||
Tags.from_strs(['platform-only']), []),
|
v.name = 'foo_PLATFORM'
|
||||||
Arch('arm'), 9, False, False))
|
self.assertOmit(f, v)
|
||||||
|
|
||||||
|
v.name = 'foo'
|
||||||
|
v.tags = Tags.from_strs(['platform-only'])
|
||||||
|
self.assertOmit(f, v)
|
||||||
|
|
||||||
def test_omit_llndk(self) -> None:
|
def test_omit_llndk(self) -> None:
|
||||||
self.assertTrue(
|
f = self.filter
|
||||||
symbolfile.should_omit_version(
|
v = self.version
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
|
v_llndk = copy(v)
|
||||||
Arch('arm'), 9, False, False))
|
v_llndk.tags = Tags.from_strs(['llndk'])
|
||||||
|
|
||||||
self.assertFalse(
|
self.assertOmit(f, v_llndk)
|
||||||
symbolfile.should_omit_version(
|
|
||||||
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
|
f.llndk = True
|
||||||
True, False))
|
self.assertInclude(f, v)
|
||||||
self.assertFalse(
|
self.assertInclude(f, v_llndk)
|
||||||
symbolfile.should_omit_version(
|
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
|
|
||||||
Arch('arm'), 9, True, False))
|
|
||||||
|
|
||||||
def test_omit_apex(self) -> None:
|
def test_omit_apex(self) -> None:
|
||||||
self.assertTrue(
|
f = self.filter
|
||||||
symbolfile.should_omit_version(
|
v = self.version
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
|
v_apex = copy(v)
|
||||||
Arch('arm'), 9, False, False))
|
v_apex.tags = Tags.from_strs(['apex'])
|
||||||
|
v_systemapi = copy(v)
|
||||||
|
v_systemapi.tags = Tags.from_strs(['systemapi'])
|
||||||
|
|
||||||
self.assertFalse(
|
self.assertOmit(f, v_apex)
|
||||||
symbolfile.should_omit_version(
|
|
||||||
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
|
f.apex = True
|
||||||
False, True))
|
self.assertInclude(f, v)
|
||||||
self.assertFalse(
|
self.assertInclude(f, v_apex)
|
||||||
symbolfile.should_omit_version(
|
self.assertOmit(f, v_systemapi)
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
|
|
||||||
Arch('arm'), 9, False, True))
|
|
||||||
|
|
||||||
def test_omit_systemapi(self) -> None:
|
def test_omit_systemapi(self) -> None:
|
||||||
self.assertTrue(
|
f = self.filter
|
||||||
symbolfile.should_omit_version(
|
v = self.version
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
|
v_apex = copy(v)
|
||||||
[]), Arch('arm'), 9, False, False))
|
v_apex.tags = Tags.from_strs(['apex'])
|
||||||
|
v_systemapi = copy(v)
|
||||||
|
v_systemapi.tags = Tags.from_strs(['systemapi'])
|
||||||
|
|
||||||
self.assertFalse(
|
self.assertOmit(f, v_systemapi)
|
||||||
symbolfile.should_omit_version(
|
|
||||||
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
|
f.systemapi = True
|
||||||
False, True))
|
self.assertInclude(f, v)
|
||||||
self.assertFalse(
|
self.assertInclude(f, v_systemapi)
|
||||||
symbolfile.should_omit_version(
|
self.assertOmit(f, v_apex)
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
|
|
||||||
[]), Arch('arm'), 9, False, True))
|
|
||||||
|
|
||||||
def test_omit_arch(self) -> None:
|
def test_omit_arch(self) -> None:
|
||||||
self.assertFalse(
|
f_arm = self.filter
|
||||||
symbolfile.should_omit_version(
|
v_none = self.version
|
||||||
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
|
self.assertInclude(f_arm, v_none)
|
||||||
False, False))
|
|
||||||
self.assertFalse(
|
|
||||||
symbolfile.should_omit_version(
|
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['arm']), []),
|
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
|
||||||
self.assertTrue(
|
v_arm = copy(v_none)
|
||||||
symbolfile.should_omit_version(
|
v_arm.tags = Tags.from_strs(['arm'])
|
||||||
symbolfile.Version('foo', None, Tags.from_strs(['x86']), []),
|
self.assertInclude(f_arm, v_arm)
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
v_x86 = copy(v_none)
|
||||||
|
v_x86.tags = Tags.from_strs(['x86'])
|
||||||
|
self.assertOmit(f_arm, v_x86)
|
||||||
|
|
||||||
def test_omit_api(self) -> None:
|
def test_omit_api(self) -> None:
|
||||||
self.assertFalse(
|
f_api9 = self.filter
|
||||||
symbolfile.should_omit_version(
|
v_none = self.version
|
||||||
symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
|
self.assertInclude(f_api9, v_none)
|
||||||
False, False))
|
|
||||||
self.assertFalse(
|
|
||||||
symbolfile.should_omit_version(
|
|
||||||
symbolfile.Version('foo', None,
|
|
||||||
Tags.from_strs(['introduced=9']), []),
|
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
|
||||||
self.assertTrue(
|
v_api9 = copy(v_none)
|
||||||
symbolfile.should_omit_version(
|
v_api9.tags = Tags.from_strs(['introduced=9'])
|
||||||
symbolfile.Version('foo', None,
|
self.assertInclude(f_api9, v_api9)
|
||||||
Tags.from_strs(['introduced=14']), []),
|
|
||||||
Arch('arm'), 9, False, False))
|
v_api14 = copy(v_none)
|
||||||
|
v_api14.tags = Tags.from_strs(['introduced=14'])
|
||||||
|
self.assertOmit(f_api9, v_api14)
|
||||||
|
|
||||||
|
|
||||||
class OmitSymbolTest(unittest.TestCase):
|
class OmitSymbolTest(unittest.TestCase):
|
||||||
def test_omit_llndk(self) -> None:
|
def setUp(self) -> None:
|
||||||
self.assertTrue(
|
self.filter = Filter(arch = Arch('arm'), api = 9)
|
||||||
symbolfile.should_omit_symbol(
|
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
|
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
|
||||||
self.assertFalse(
|
def assertOmit(self, f: Filter, s: Symbol) -> None:
|
||||||
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
|
self.assertTrue(f.should_omit_symbol(s))
|
||||||
Arch('arm'), 9, True, False))
|
|
||||||
self.assertFalse(
|
def assertInclude(self, f: Filter, s: Symbol) -> None:
|
||||||
symbolfile.should_omit_symbol(
|
self.assertFalse(f.should_omit_symbol(s))
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
|
|
||||||
Arch('arm'), 9, True, False))
|
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:
|
def test_omit_apex(self) -> None:
|
||||||
self.assertTrue(
|
f_none = self.filter
|
||||||
symbolfile.should_omit_symbol(
|
f_apex = copy(f_none)
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
|
f_apex.apex = True
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
|
||||||
self.assertFalse(
|
s_none = Symbol('foo', Tags())
|
||||||
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
|
s_apex = Symbol('foo', Tags.from_strs(['apex']))
|
||||||
Arch('arm'), 9, False, True))
|
s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
|
||||||
self.assertFalse(
|
|
||||||
symbolfile.should_omit_symbol(
|
self.assertOmit(f_none, s_apex)
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
|
self.assertInclude(f_apex, s_none)
|
||||||
Arch('arm'), 9, False, True))
|
self.assertInclude(f_apex, s_apex)
|
||||||
|
self.assertOmit(f_apex, s_systemapi)
|
||||||
|
|
||||||
def test_omit_systemapi(self) -> None:
|
def test_omit_systemapi(self) -> None:
|
||||||
self.assertTrue(
|
f_none = self.filter
|
||||||
symbolfile.should_omit_symbol(
|
f_systemapi = copy(f_none)
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
|
f_systemapi.systemapi = True
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
|
||||||
self.assertFalse(
|
s_none = Symbol('foo', Tags())
|
||||||
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
|
s_apex = Symbol('foo', Tags.from_strs(['apex']))
|
||||||
Arch('arm'), 9, False, True))
|
s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
|
||||||
self.assertFalse(
|
|
||||||
symbolfile.should_omit_symbol(
|
self.assertOmit(f_none, s_systemapi)
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
|
self.assertInclude(f_systemapi, s_none)
|
||||||
Arch('arm'), 9, False, True))
|
self.assertInclude(f_systemapi, s_systemapi)
|
||||||
|
self.assertOmit(f_systemapi, s_apex)
|
||||||
|
|
||||||
|
def test_omit_apex_and_systemapi(self) -> None:
|
||||||
|
f = self.filter
|
||||||
|
f.systemapi = True
|
||||||
|
f.apex = True
|
||||||
|
|
||||||
|
s_none = Symbol('foo', Tags())
|
||||||
|
s_apex = Symbol('foo', Tags.from_strs(['apex']))
|
||||||
|
s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
|
||||||
|
self.assertInclude(f, s_none)
|
||||||
|
self.assertInclude(f, s_apex)
|
||||||
|
self.assertInclude(f, s_systemapi)
|
||||||
|
|
||||||
def test_omit_arch(self) -> None:
|
def test_omit_arch(self) -> None:
|
||||||
self.assertFalse(
|
f_arm = self.filter
|
||||||
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
|
s_none = Symbol('foo', Tags())
|
||||||
Arch('arm'), 9, False, False))
|
s_arm = Symbol('foo', Tags.from_strs(['arm']))
|
||||||
self.assertFalse(
|
s_x86 = Symbol('foo', Tags.from_strs(['x86']))
|
||||||
symbolfile.should_omit_symbol(
|
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['arm'])), Arch('arm'),
|
|
||||||
9, False, False))
|
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertInclude(f_arm, s_none)
|
||||||
symbolfile.should_omit_symbol(
|
self.assertInclude(f_arm, s_arm)
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['x86'])), Arch('arm'),
|
self.assertOmit(f_arm, s_x86)
|
||||||
9, False, False))
|
|
||||||
|
|
||||||
def test_omit_api(self) -> None:
|
def test_omit_api(self) -> None:
|
||||||
self.assertFalse(
|
f_api9 = self.filter
|
||||||
symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
|
s_none = Symbol('foo', Tags())
|
||||||
Arch('arm'), 9, False, False))
|
s_api9 = Symbol('foo', Tags.from_strs(['introduced=9']))
|
||||||
self.assertFalse(
|
s_api14 = Symbol('foo', Tags.from_strs(['introduced=14']))
|
||||||
symbolfile.should_omit_symbol(
|
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['introduced=9'])),
|
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertInclude(f_api9, s_none)
|
||||||
symbolfile.should_omit_symbol(
|
self.assertInclude(f_api9, s_api9)
|
||||||
symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])),
|
self.assertOmit(f_api9, s_api14)
|
||||||
Arch('arm'), 9, False, False))
|
|
||||||
|
|
||||||
|
|
||||||
class SymbolFileParseTest(unittest.TestCase):
|
class SymbolFileParseTest(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.filter = Filter(arch = Arch('arm'), api = 16)
|
||||||
|
|
||||||
def test_next_line(self) -> None:
|
def test_next_line(self) -> None:
|
||||||
input_file = io.StringIO(textwrap.dedent("""\
|
input_file = io.StringIO(textwrap.dedent("""\
|
||||||
foo
|
foo
|
||||||
@@ -382,8 +393,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
# baz
|
# baz
|
||||||
qux
|
qux
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
self.assertIsNone(parser.current_line)
|
self.assertIsNone(parser.current_line)
|
||||||
|
|
||||||
self.assertEqual('foo', parser.next_line().strip())
|
self.assertEqual('foo', parser.next_line().strip())
|
||||||
@@ -409,8 +419,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
VERSION_2 {
|
VERSION_2 {
|
||||||
} VERSION_1; # asdf
|
} VERSION_1; # asdf
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
version = parser.parse_version()
|
version = parser.parse_version()
|
||||||
@@ -419,8 +428,8 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
self.assertEqual(Tags.from_strs(['foo', 'bar']), version.tags)
|
self.assertEqual(Tags.from_strs(['foo', 'bar']), version.tags)
|
||||||
|
|
||||||
expected_symbols = [
|
expected_symbols = [
|
||||||
symbolfile.Symbol('baz', Tags()),
|
Symbol('baz', Tags()),
|
||||||
symbolfile.Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
|
Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
|
||||||
]
|
]
|
||||||
self.assertEqual(expected_symbols, version.symbols)
|
self.assertEqual(expected_symbols, version.symbols)
|
||||||
|
|
||||||
@@ -434,8 +443,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
input_file = io.StringIO(textwrap.dedent("""\
|
input_file = io.StringIO(textwrap.dedent("""\
|
||||||
VERSION_1 {
|
VERSION_1 {
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
with self.assertRaises(symbolfile.ParseError):
|
with self.assertRaises(symbolfile.ParseError):
|
||||||
parser.parse_version()
|
parser.parse_version()
|
||||||
@@ -446,8 +454,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
foo:
|
foo:
|
||||||
}
|
}
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
with self.assertRaises(symbolfile.ParseError):
|
with self.assertRaises(symbolfile.ParseError):
|
||||||
parser.parse_version()
|
parser.parse_version()
|
||||||
@@ -457,8 +464,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
foo;
|
foo;
|
||||||
bar; # baz qux
|
bar; # baz qux
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
symbol = parser.parse_symbol()
|
symbol = parser.parse_symbol()
|
||||||
@@ -476,8 +482,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
with self.assertRaises(symbolfile.ParseError):
|
with self.assertRaises(symbolfile.ParseError):
|
||||||
parser.parse_version()
|
parser.parse_version()
|
||||||
@@ -489,8 +494,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
version = parser.parse_version()
|
version = parser.parse_version()
|
||||||
self.assertEqual([], version.symbols)
|
self.assertEqual([], version.symbols)
|
||||||
@@ -501,8 +505,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
foo
|
foo
|
||||||
};
|
};
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
with self.assertRaises(symbolfile.ParseError):
|
with self.assertRaises(symbolfile.ParseError):
|
||||||
parser.parse_version()
|
parser.parse_version()
|
||||||
@@ -510,8 +513,7 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
def test_parse_fails_invalid_input(self) -> None:
|
def test_parse_fails_invalid_input(self) -> None:
|
||||||
with self.assertRaises(symbolfile.ParseError):
|
with self.assertRaises(symbolfile.ParseError):
|
||||||
input_file = io.StringIO('foo')
|
input_file = io.StringIO('foo')
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
16, False, False)
|
|
||||||
parser.parse()
|
parser.parse()
|
||||||
|
|
||||||
def test_parse(self) -> None:
|
def test_parse(self) -> None:
|
||||||
@@ -532,19 +534,18 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
qwerty;
|
qwerty;
|
||||||
} VERSION_1;
|
} VERSION_1;
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
|
||||||
False, False)
|
|
||||||
versions = parser.parse()
|
versions = parser.parse()
|
||||||
|
|
||||||
expected = [
|
expected = [
|
||||||
symbolfile.Version('VERSION_1', None, Tags(), [
|
symbolfile.Version('VERSION_1', None, Tags(), [
|
||||||
symbolfile.Symbol('foo', Tags()),
|
Symbol('foo', Tags()),
|
||||||
symbolfile.Symbol('bar', Tags.from_strs(['baz'])),
|
Symbol('bar', Tags.from_strs(['baz'])),
|
||||||
]),
|
]),
|
||||||
symbolfile.Version(
|
symbolfile.Version(
|
||||||
'VERSION_2', 'VERSION_1', Tags.from_strs(['wasd']), [
|
'VERSION_2', 'VERSION_1', Tags.from_strs(['wasd']), [
|
||||||
symbolfile.Symbol('woodly', Tags()),
|
Symbol('woodly', Tags()),
|
||||||
symbolfile.Symbol('doodly', Tags.from_strs(['asdf'])),
|
Symbol('doodly', Tags.from_strs(['asdf'])),
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -559,8 +560,9 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
qux; # apex
|
qux; # apex
|
||||||
};
|
};
|
||||||
"""))
|
"""))
|
||||||
parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
|
f = copy(self.filter)
|
||||||
False, True)
|
f.llndk = True
|
||||||
|
parser = symbolfile.SymbolFileParser(input_file, {}, f)
|
||||||
|
|
||||||
parser.next_line()
|
parser.next_line()
|
||||||
version = parser.parse_version()
|
version = parser.parse_version()
|
||||||
@@ -568,10 +570,10 @@ class SymbolFileParseTest(unittest.TestCase):
|
|||||||
self.assertIsNone(version.base)
|
self.assertIsNone(version.base)
|
||||||
|
|
||||||
expected_symbols = [
|
expected_symbols = [
|
||||||
symbolfile.Symbol('foo', Tags()),
|
Symbol('foo', Tags()),
|
||||||
symbolfile.Symbol('bar', Tags.from_strs(['llndk'])),
|
Symbol('bar', Tags.from_strs(['llndk'])),
|
||||||
symbolfile.Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
|
Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
|
||||||
symbolfile.Symbol('qux', Tags.from_strs(['apex'])),
|
Symbol('qux', Tags.from_strs(['apex'])),
|
||||||
]
|
]
|
||||||
self.assertEqual(expected_symbols, version.symbols)
|
self.assertEqual(expected_symbols, version.symbols)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user