Properly ignore core types when generating code

This commit is contained in:
Lonami Exo 2017-09-04 16:29:00 +02:00
parent e8cdcf369d
commit 0e45f46ad5
5 changed files with 23 additions and 18 deletions

View File

@ -232,12 +232,6 @@ P.S.: I may have lied a bit. The ``TL`` language is not that easy. But it's not
You're free to sniff the ``parser/`` files and learn how to parse other more complex lines. You're free to sniff the ``parser/`` files and learn how to parse other more complex lines.
Or simply use that code and change the `SourceBuilder <telethon_generator/parser/source_builder.py>`_! Or simply use that code and change the `SourceBuilder <telethon_generator/parser/source_builder.py>`_!
Notes about the code generator
------------------------------
The code generator will skip the types considered as *core types*. These types are usually included in
almost every programming language, such as boolean values or lists, and also the Telegram True flag,
which is *not* sent but rather used to determine whether that flag should be enabled or not.
Updating the ``scheme.tl`` Updating the ``scheme.tl``
-------------------------- --------------------------
Have you found a more updated version of the ``scheme.tl`` file? Those are great news! Updating is as simple Have you found a more updated version of the ``scheme.tl`` file? Those are great news! Updating is as simple

View File

@ -4,7 +4,12 @@ from zlib import crc32
class TLObject: class TLObject:
""".tl core types IDs (such as vector, booleans, etc.)""" """.tl core types IDs (such as vector, booleans, etc.)"""
CORE_TYPES = (0x1cb5c415, 0xbc799737, 0x997275b5, 0x3fedd339) CORE_TYPES = (
0xbc799737, # boolFalse#bc799737 = Bool;
0x997275b5, # boolTrue#997275b5 = Bool;
0x3fedd339, # true#3fedd339 = True;
0x1cb5c415, # vector#1cb5c415 {t:Type} # [ t ] = Vector t;
)
def __init__(self, fullname, object_id, args, result, is_function): def __init__(self, fullname, object_id, args, result, is_function):
""" """
@ -65,6 +70,10 @@ class TLObject:
;$ # Finally, the line should always end with ; ;$ # Finally, the line should always end with ;
''', tl, re.IGNORECASE | re.VERBOSE) ''', tl, re.IGNORECASE | re.VERBOSE)
if match is None:
# Probably "vector#1cb5c415 {t:Type} # [ t ] = Vector t;"
raise ValueError('Cannot parse TLObject', tl)
# Sub-regex to match the arguments (sadly, it cannot be embedded in the first regex) # Sub-regex to match the arguments (sadly, it cannot be embedded in the first regex)
args_match = re.findall(r''' args_match = re.findall(r'''
({)? # We may or may not capture the opening brace ({)? # We may or may not capture the opening brace

View File

@ -7,7 +7,7 @@ class TLParser:
"""Class used to parse .tl files""" """Class used to parse .tl files"""
@staticmethod @staticmethod
def parse_file(file_path): def parse_file(file_path, ignore_core=False):
"""This method yields TLObjects from a given .tl file""" """This method yields TLObjects from a given .tl file"""
with open(file_path, encoding='utf-8') as file: with open(file_path, encoding='utf-8') as file:
@ -28,7 +28,13 @@ class TLParser:
is_function = following_types == 'functions' is_function = following_types == 'functions'
else: else:
yield TLObject.from_tl(line, is_function) try:
result = TLObject.from_tl(line, is_function)
if not ignore_core or not result.is_core_type():
yield result
except ValueError as e:
if 'vector#1cb5c415' not in str(e):
raise
@staticmethod @staticmethod
def find_layer(file_path): def find_layer(file_path):

View File

@ -128,12 +128,12 @@ contest.saveDeveloperInfo#9a5f6e95 vk_id:int name:string phone_number:string age
---types--- ---types---
//boolFalse#bc799737 = Bool; boolFalse#bc799737 = Bool;
//boolTrue#997275b5 = Bool; boolTrue#997275b5 = Bool;
//true#3fedd339 = True; true#3fedd339 = True;
//vector#1cb5c415 {t:Type} # [ t ] = Vector t; vector#1cb5c415 {t:Type} # [ t ] = Vector t;
error#c4b9f9bb code:int text:string = Error; error#c4b9f9bb code:int text:string = Error;

View File

@ -45,7 +45,7 @@ class TLGenerator:
os.makedirs(self._get_file('types'), exist_ok=True) os.makedirs(self._get_file('types'), exist_ok=True)
# Step 0: Cache the parsed file on a tuple # Step 0: Cache the parsed file on a tuple
tlobjects = tuple(TLParser.parse_file(scheme_file)) tlobjects = tuple(TLParser.parse_file(scheme_file, ignore_core=True))
# Step 1: Group everything by {namespace: [tlobjects]} so we can # Step 1: Group everything by {namespace: [tlobjects]} so we can
# easily generate __init__.py files with all the TLObjects on them. # easily generate __init__.py files with all the TLObjects on them.
@ -138,10 +138,6 @@ class TLGenerator:
# Generate the class for every TLObject # Generate the class for every TLObject
for t in sorted(tlobjects, key=lambda x: x.name): for t in sorted(tlobjects, key=lambda x: x.name):
# Omit core types, they're embedded in the code
if t.is_core_type():
continue
TLGenerator._write_source_code( TLGenerator._write_source_code(
t, builder, depth, type_constructors t, builder, depth, type_constructors
) )