Skip to content

Commit 0e7012d

Browse files
author
Kostiantyn Sologubov
committed
Merge branch 'SDL-0234-keywords' into SDL-0234-Proxy-Library-RPC-Generation
# Conflicts: # generator/rpc_spec
2 parents 590fc81 + 7a4ff35 commit 0e7012d

8 files changed

Lines changed: 91 additions & 40 deletions

File tree

generator/generator.py

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -242,40 +242,66 @@ def versions_compatibility_validating(self):
242242
self.logger.info('Parser type: %s, version %s,\tGenerator version %s',
243243
basename(getfile(Parser().__class__)), parser_origin, self.get_version)
244244

245+
def get_file_content(self, file_name: Path) -> list:
246+
"""
247+
248+
:param file_name:
249+
:return:
250+
"""
251+
try:
252+
with file_name.open('r') as file:
253+
content = file.readlines()
254+
return content
255+
except FileNotFoundError as message1:
256+
self.logger.error(message1)
257+
return []
258+
259+
def get_key_words(self, file_name=ROOT.joinpath('rpc_spec/RpcParser/RESERVED_KEYWORDS')):
260+
"""
261+
:param file_name:
262+
:return:
263+
"""
264+
content = self.get_file_content(file_name)
265+
content = tuple(map(lambda e: re.sub(r'\n', r'', e).strip().casefold(), content))
266+
try:
267+
content = tuple(filter(lambda e: not re.search(r'^#+\s+.+|^$', e), content))
268+
self.logger.debug('key_words: %s', ', '.join(content))
269+
return content
270+
except (IndexError, ValueError, StopIteration) as error1:
271+
self.logger.error('Error while getting key_words, %s %s', type(error1).__name__, error1)
272+
return []
273+
245274
def get_paths(self, file_name=ROOT.joinpath('paths.ini')):
246275
"""
247276
:param file_name: path to file with Paths
248277
:return: namedtuple with Paths to key elements
249278
"""
250279
fields = ('struct_class', 'request_class', 'response_class',
251280
'notification_class', 'enums_package', 'structs_package', 'functions_package')
252-
intermediate = OrderedDict()
253-
try:
254-
with file_name.open('r') as file:
255-
for line in file:
256-
if line.startswith('#'):
257-
self.logger.warning('commented property %s, which will be skipped', line.strip())
258-
continue
259-
if re.match(r'^(\w+)\s?=\s?(.+)', line):
260-
if len(line.split('=')) > 2:
261-
self.logger.critical('can not evaluate value, too many separators %s', str(line))
262-
sys.exit(1)
263-
name, var = line.partition('=')[::2]
264-
if name.strip() in intermediate:
265-
self.logger.critical('duplicate key %s', name)
266-
sys.exit(1)
267-
intermediate[name.strip().lower()] = var.strip()
268-
except FileNotFoundError as message1:
269-
self.logger.critical(message1)
270-
sys.exit(1)
281+
data = OrderedDict()
282+
content = self.get_file_content(file_name)
283+
284+
for line in content:
285+
if line.startswith('#'):
286+
self.logger.warning('commented property %s, which will be skipped', line.strip())
287+
continue
288+
if re.match(r'^(\w+)\s?=\s?(.+)', line):
289+
if len(line.split('=')) > 2:
290+
self.logger.critical('can not evaluate value, too many separators %s', str(line))
291+
sys.exit(1)
292+
name, var = line.partition('=')[::2]
293+
if name.strip() in data:
294+
self.logger.critical('duplicate key %s', name)
295+
sys.exit(1)
296+
data[name.strip().lower()] = var.strip()
271297

272298
for line in fields:
273-
if line not in intermediate:
274-
self.logger.critical('in %s missed fields: %s ', file, str(line))
299+
if line not in data:
300+
self.logger.critical('in %s missed fields: %s ', content, str(line))
275301
sys.exit(1)
276302

277303
Paths = namedtuple('Paths', ' '.join(fields))
278-
return Paths(**intermediate)
304+
return Paths(**data)
279305

280306
def write_file(self, file_name, template, data):
281307
"""
@@ -399,16 +425,17 @@ def main(self):
399425
pattern=args.regex_pattern)
400426

401427
paths = self.get_paths()
428+
key_words = self.get_key_words()
402429

403430
if args.enums and interface.enums:
404431
self.process(args.output_directory, args.skip, args.overwrite, tuple(interface.enums.values()),
405-
EnumsProducer(paths))
432+
EnumsProducer(paths, key_words))
406433
if args.structs and interface.structs:
407434
self.process(args.output_directory, args.skip, args.overwrite, tuple(interface.structs.values()),
408-
StructsProducer(paths, enum_names, struct_names))
435+
StructsProducer(paths, enum_names, struct_names, key_words))
409436
if args.functions and interface.functions:
410437
self.process(args.output_directory, args.skip, args.overwrite, tuple(interface.functions.values()),
411-
FunctionsProducer(paths, enum_names, struct_names))
438+
FunctionsProducer(paths, enum_names, struct_names, key_words))
412439

413440

414441
if __name__ == '__main__':

generator/test/test_enums.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
from model.enum import Enum
55
from model.enum_element import EnumElement
66
from transformers.enums_producer import EnumsProducer
7+
from generator import Generator
78

89

910
class TestEnumsProducer(unittest.TestCase):
1011
def setUp(self):
1112
self.maxDiff = None
1213
Paths = namedtuple('Prop', 'enums_package')
1314
paths = Paths(enums_package='com.smartdevicelink.proxy.rpc.enums')
14-
self.producer = EnumsProducer(paths)
15+
keywords = Generator().get_key_words()
16+
self.producer = EnumsProducer(paths, keywords)
1517

1618
def comparison(self, expected, actual):
1719
actual = OrderedDict(sorted(actual.items()))

generator/test/test_functions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from model.string import String
1414
from model.struct import Struct
1515
from transformers.functions_producer import FunctionsProducer
16+
from generator import Generator
1617

1718

1819
class TestFunctionsProducer(unittest.TestCase):
@@ -33,7 +34,8 @@ def setUp(self):
3334
self.expected_template['deprecated'] = None
3435
enum_names = ('FileType', 'Language')
3536
struct_names = ('SdlMsgVersion', 'TemplateColorScheme', 'TTSChunk', 'Choice')
36-
self.producer = FunctionsProducer(paths, enum_names, struct_names)
37+
keywords = Generator().get_key_words()
38+
self.producer = FunctionsProducer(paths, enum_names, struct_names, keywords)
3739

3840
def comparison(self, expected, actual):
3941
actual_params = dict(zip(map(lambda k: k.title, actual['params']), actual['params']))

generator/test/test_structs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from model.string import String
99
from model.struct import Struct
1010
from transformers.structs_producer import StructsProducer
11+
from generator import Generator
1112

1213

1314
class TestStructsProducer(unittest.TestCase):
@@ -17,7 +18,8 @@ def setUp(self):
1718
paths = Paths(enums_package='com.smartdevicelink.proxy.rpc.enums',
1819
structs_package='com.smartdevicelink.proxy.rpc',
1920
struct_class='com.smartdevicelink.proxy.RPCStruct')
20-
self.producer = StructsProducer(paths, ['SamplingRate'], ('Image',))
21+
keywords = Generator().get_key_words()
22+
self.producer = StructsProducer(paths, ['SamplingRate'], ('Image',), keywords)
2123

2224
def comparison(self, expected, actual):
2325
actual_params = dict(zip(map(lambda k: k.origin, actual['params']), actual['params']))

generator/transformers/common_producer.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ class InterfaceProducerCommon(ABC):
2020
version = '1.0.0'
2121

2222
def __init__(self, container_name, enums_package, structs_package, package_name,
23-
enum_names=(), struct_names=()):
23+
enum_names=(), struct_names=(), key_words=()):
2424
self.logger = logging.getLogger('Generator.InterfaceProducerCommon')
2525
self.container_name = container_name
2626
self.enum_names = enum_names
2727
self.struct_names = struct_names
28+
self.key_words = key_words
2829
self.enums_package = enums_package
2930
self.structs_package = structs_package
3031
self.package_name = package_name
@@ -85,6 +86,20 @@ def replace_sync(name):
8586
return re.sub(r'^([sS])ync(.+)$', r'\1dl\2', name)
8687
return name
8788

89+
def replace_keywords(self, name: str = '') -> str:
90+
"""
91+
if :param name in self.key_words, :return: name += 'Param'
92+
:param name: string with item name
93+
"""
94+
if any(map(lambda k: re.search(r'^(get|set|key_)?{}$'.format(name.casefold()), k), self.key_words)):
95+
origin = name
96+
if name.isupper():
97+
name += '_PARAM'
98+
else:
99+
name += 'Param'
100+
self.logger.debug('Replacing %s with %s', origin, name)
101+
return self.replace_sync(name)
102+
88103
def extract_type(self, param):
89104
"""
90105
Evaluate and extract type

generator/transformers/enums_producer.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ class EnumsProducer(InterfaceProducerCommon):
1616
Enums transformation
1717
"""
1818

19-
def __init__(self, paths):
19+
def __init__(self, paths, key_words):
2020
super(EnumsProducer, self).__init__(
2121
container_name='elements',
2222
enums_package=None,
2323
structs_package=None,
24-
package_name=paths.enums_package)
24+
package_name=paths.enums_package,
25+
key_words=key_words)
2526
self.logger = logging.getLogger('EnumsProducer')
2627
self._params = namedtuple('params', 'origin name internal description since value deprecated')
2728

generator/transformers/functions_producer.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ class FunctionsProducer(InterfaceProducerCommon):
1616
Functions transformation
1717
"""
1818

19-
def __init__(self, paths, enum_names, struct_names):
19+
def __init__(self, paths, enum_names, struct_names, key_words):
2020
super(FunctionsProducer, self).__init__(
2121
container_name='params',
2222
enums_package=paths.enums_package,
2323
structs_package=paths.structs_package,
2424
enum_names=enum_names,
2525
struct_names=struct_names,
26-
package_name=paths.functions_package)
26+
package_name=paths.functions_package,
27+
key_words=key_words)
2728
self.logger = logging.getLogger('FunctionsProducer')
2829
self.request_class = paths.request_class
2930
self.response_class = paths.response_class
@@ -36,7 +37,7 @@ def transform(self, item: Function) -> dict:
3637
:param item: particular element from initial Model
3738
:return: dictionary to be applied to jinja2 template
3839
"""
39-
class_name = self.replace_sync(item.name[:1].upper() + item.name[1:])
40+
class_name = self.replace_keywords(item.name[:1].upper() + item.name[1:])
4041

4142
imports = {'java.util.Hashtable', 'com.smartdevicelink.protocol.enums.FunctionID'}
4243
extends_class = None
@@ -58,7 +59,7 @@ def transform(self, item: Function) -> dict:
5859

5960
for param in getattr(item, self.container_name).values():
6061
param.origin = param.name
61-
param.name = self.replace_sync(param.name)
62+
param.name = self.replace_keywords(param.name)
6263
i, p = self.extract_param(param)
6364
imports.update(i)
6465
params.update({param.name: p})
@@ -67,7 +68,7 @@ def transform(self, item: Function) -> dict:
6768
render['kind'] = item.message_type.name
6869
render['package_name'] = self.package_name
6970
render['imports'] = self.sort_imports(imports)
70-
render['function_id'] = self.key(self.replace_sync(item.name))
71+
render['function_id'] = self.key(self.replace_keywords(item.name))
7172
render['class_name'] = class_name
7273
render['extends_class'] = extends_class
7374
render['since'] = item.since

generator/transformers/structs_producer.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ class StructsProducer(InterfaceProducerCommon):
1616
Structs transformation
1717
"""
1818

19-
def __init__(self, paths, enum_names, struct_names):
19+
def __init__(self, paths, enum_names, struct_names, key_words):
2020
super(StructsProducer, self).__init__(
2121
container_name='members',
2222
enums_package=paths.enums_package,
2323
structs_package=paths.structs_package,
2424
enum_names=enum_names,
2525
struct_names=struct_names,
26-
package_name=paths.structs_package)
26+
package_name=paths.structs_package,
27+
key_words=key_words)
2728
self.logger = logging.getLogger('StructsProducer')
2829
self.struct_class = paths.struct_class
2930

@@ -33,7 +34,7 @@ def transform(self, item: Struct) -> dict:
3334
:param item: particular element from initial Model
3435
:return: dictionary to be applied to jinja2 template
3536
"""
36-
class_name = self.replace_sync(item.name[:1].upper() + item.name[1:])
37+
class_name = self.replace_keywords(item.name[:1].upper() + item.name[1:])
3738

3839
imports = {'java.util.Hashtable'}
3940
extends_class = self.struct_class
@@ -44,7 +45,7 @@ def transform(self, item: Struct) -> dict:
4445
params = OrderedDict()
4546

4647
for param in getattr(item, self.container_name).values():
47-
param.name = self.replace_sync(param.name)
48+
param.name = self.replace_keywords(param.name)
4849
i, p = self.extract_param(param)
4950
imports.update(i)
5051
params[param.name] = p

0 commit comments

Comments
 (0)