fixing issues with callbacks
This commit is contained in:
parent
fe66f41ddd
commit
eb0625be1a
@ -7,4 +7,4 @@ cd "$( dirname -- "$0"; )"
|
||||
cd ..
|
||||
|
||||
rm -rf temp
|
||||
nope-py-prepare-code --input dist-py --output temp --type js
|
||||
nope-py-prepare-code --input dist-py --output temp --type js --convert_snake_case
|
@ -6,6 +6,7 @@ __version__ = '0.1.0'
|
||||
|
||||
from .logger import get_logger
|
||||
from .post_processor import post_process
|
||||
from .helpers import define_dotted_dict, to_snake_case
|
||||
from .js import get_parser as get_parser_js, transform as transform_js
|
||||
from .ts import get_parser as get_parser_ts, transform as transform_ts
|
||||
from .main import main
|
36
py-helpers/prepare_code/helpers.py
Normal file
36
py-helpers/prepare_code/helpers.py
Normal file
@ -0,0 +1,36 @@
|
||||
import ast, _ast
|
||||
|
||||
CODE = '''class dotted_dict(dict):
|
||||
"""dot.notation access to dictionary attributes"""
|
||||
__getattr__ = dict.get
|
||||
__setattr__ = dict.__setitem__
|
||||
__delattr__ = dict.__delitem__'''
|
||||
|
||||
def to_snake_case(str:str)->str:
|
||||
""" Helper to convert the string to the snake-case
|
||||
|
||||
Args:
|
||||
str (str): The string to convert
|
||||
|
||||
Returns:
|
||||
str: The converted string
|
||||
"""
|
||||
if str == str.upper():
|
||||
return str
|
||||
|
||||
ret = ''.join(['_'+i.lower() if i.isupper()
|
||||
else i for i in str]).lstrip('_')
|
||||
|
||||
if ret.startswith("_"):
|
||||
ret[1:]
|
||||
|
||||
return ret
|
||||
|
||||
def define_dotted_dict(type= "name"):
|
||||
""" Returns the Deinfition of the dotdict class
|
||||
"""
|
||||
|
||||
if (type == "name"):
|
||||
return _ast.Name(id= "dotted_dict")
|
||||
|
||||
return ast.parse(CODE).body[0]
|
@ -141,11 +141,11 @@ decrement: accessor "--"
|
||||
|
||||
invert: "!" ret_expr
|
||||
|
||||
instanceof: id "instanceof" id
|
||||
instanceof.100: id "instanceof" id
|
||||
|
||||
typeof: "typeof" accessor
|
||||
typeof.100: "typeof" accessor
|
||||
|
||||
delete_stmt: "delete" accessor
|
||||
delete_stmt.100: "delete" accessor
|
||||
|
||||
await_stmt: "await" ret_expr
|
||||
|
||||
@ -355,21 +355,21 @@ break_statement: "break"
|
||||
|
||||
// Define a If - Statement
|
||||
// We have to consider "if" "else if" and "else"
|
||||
if_statement: "if" "(" ret_expr ")" body_or_expr_with_terminator [else_if_statements] [else_statement]
|
||||
if_statement.10: "if" "(" ret_expr ")" body_or_expr_with_terminator [else_if_statements] [else_statement]
|
||||
else_if_statements: else_if_statement+
|
||||
else_if_statement: "else" "if" "(" ret_expr ")" body_or_expr_with_terminator
|
||||
else_statement: "else" body_or_expr_with_terminator
|
||||
else_if_statement.9: "else" "if" "(" ret_expr ")" body_or_expr_with_terminator
|
||||
else_statement.9: "else" body_or_expr_with_terminator
|
||||
|
||||
inline_if: ret_expr "?" ret_expr ":" ret_expr
|
||||
inline_if.10: ret_expr "?" ret_expr ":" ret_expr
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// switch-case
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
switch: "switch" "(" ret_expr ")" switch_body
|
||||
switch_body: "{" (switch_case* [switch_default])* "}"
|
||||
switch_case: "case" ret_expr ":" switch_case_body
|
||||
switch_default: "default" ":" switch_case_body
|
||||
switch.10: "switch" "(" ret_expr ")" switch_body
|
||||
switch_body.9: "{" (switch_case* [switch_default])* "}"
|
||||
switch_case.8: "case" ret_expr ":" switch_case_body
|
||||
switch_default.7: "default" ":" switch_case_body
|
||||
|
||||
switch_case_body: ("{" switch_case_statements "}")
|
||||
| switch_case_statements
|
||||
|
@ -5,16 +5,9 @@ import logging
|
||||
|
||||
# from prepare_code import get_logger
|
||||
from ..logger import get_logger
|
||||
from ..helpers import to_snake_case, define_dotted_dict
|
||||
from lark import Transformer
|
||||
|
||||
|
||||
def to_snake_case(str):
|
||||
if str == str.upper():
|
||||
return str
|
||||
return ''.join(['_'+i.lower() if i.isupper()
|
||||
else i for i in str]).lstrip('_')
|
||||
|
||||
|
||||
class CodeTransformeJs(Transformer):
|
||||
|
||||
def __init__(self, visit_tokens: bool = True, level=logging.INFO, to_snake_case=False, switch_case_to_if_else=True, **kwargs) -> None:
|
||||
@ -87,6 +80,7 @@ class CodeTransformeJs(Transformer):
|
||||
"switch",
|
||||
"try_catch",
|
||||
"class_statement",
|
||||
# "constructor",
|
||||
# "method",
|
||||
# "async_method",
|
||||
"start"
|
||||
@ -150,6 +144,8 @@ class CodeTransformeJs(Transformer):
|
||||
try:
|
||||
self._logger.debug(
|
||||
f"calling '{__name}' resulted in result={ast.dump(items[0])}")
|
||||
self._logger.debug(
|
||||
f"calling '{__name}' created node-id={items[0]}")
|
||||
except:
|
||||
self._logger.debug(
|
||||
f"calling '{__name}' resulted in result={items[0]}")
|
||||
@ -197,7 +193,7 @@ class CodeTransformeJs(Transformer):
|
||||
self._log(__name, items)
|
||||
|
||||
# Call the original Function
|
||||
result = attr(items)
|
||||
result = attr(items, **kwargs)
|
||||
|
||||
try:
|
||||
self._logger.debug(
|
||||
@ -207,9 +203,11 @@ class CodeTransformeJs(Transformer):
|
||||
f"calling '{__name}' resulted in result={result}")
|
||||
|
||||
try:
|
||||
# Test if the Elment does not contain a body.
|
||||
if __name not in _contains_body and type(result) not in (list, tuple, dict):
|
||||
# Now register some callbacks:
|
||||
self._add_to_tree(result, items)
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
@ -267,11 +265,13 @@ class CodeTransformeJs(Transformer):
|
||||
for item in items:
|
||||
if type(item) is list:
|
||||
to_check += item
|
||||
else:
|
||||
elif item is not None:
|
||||
to_check.append(item)
|
||||
else:
|
||||
elif items is not None:
|
||||
to_check.append(items)
|
||||
|
||||
self._logger.debug(f"'_add_to_tree' -> '{ret}' checks {to_check}")
|
||||
|
||||
for item in to_check:
|
||||
try:
|
||||
self._add_to_tree_single(ret, item)
|
||||
@ -281,11 +281,6 @@ class CodeTransformeJs(Transformer):
|
||||
def _add_to_tree_single(self, parent, item):
|
||||
id = item
|
||||
|
||||
try:
|
||||
id = item.name
|
||||
except:
|
||||
pass
|
||||
|
||||
if id in self._ids_to_anonymous_func:
|
||||
if parent not in self._anonymous_func_tree:
|
||||
self._anonymous_func_tree[parent] = set()
|
||||
@ -293,6 +288,19 @@ class CodeTransformeJs(Transformer):
|
||||
self._anonymous_func_tree[parent].add(
|
||||
self._ids_to_anonymous_func[id]
|
||||
)
|
||||
|
||||
self._logger.debug(f"\t\t'{parent}' added defintions (function_defintion) for {self._anonymous_func_tree[parent]}")
|
||||
|
||||
elif id in self._anonymous_func_to_ids:
|
||||
if parent not in self._anonymous_func_tree:
|
||||
self._anonymous_func_tree[parent] = set()
|
||||
|
||||
self._anonymous_func_tree[parent].add(
|
||||
id
|
||||
)
|
||||
|
||||
self._logger.debug(f"\t\t'{parent}' added defintions (a function) for {self._anonymous_func_tree[parent]}")
|
||||
|
||||
elif item in self._anonymous_func_tree:
|
||||
if parent not in self._anonymous_func_tree:
|
||||
self._anonymous_func_tree[parent] = set()
|
||||
@ -302,11 +310,19 @@ class CodeTransformeJs(Transformer):
|
||||
self._anonymous_func_tree[parent] = s.union(
|
||||
self._anonymous_func_tree[item])
|
||||
|
||||
self._logger.debug(f"\t\t'{parent}' added defintions (a containing node) for {self._anonymous_func_tree[parent]}")
|
||||
|
||||
else:
|
||||
self._logger.debug(f"\t\tfailed to find function for '{id}'")
|
||||
self._logger.debug(f"\t\t_anonymous_func_to_ids: '{self._anonymous_func_to_ids}'")
|
||||
self._logger.debug(f"\t\t_ids_to_anonymous_func: '{self._ids_to_anonymous_func}'")
|
||||
|
||||
def _adapt_body(self, body):
|
||||
defintions_to_add = set()
|
||||
|
||||
for item in body:
|
||||
if item in self._anonymous_func_tree:
|
||||
self._logger.debug(f"Found callback items for {item}")
|
||||
defintions_to_add = defintions_to_add.union(
|
||||
self._anonymous_func_tree[item])
|
||||
self._anonymous_func_tree.pop(item)
|
||||
@ -327,13 +343,13 @@ class CodeTransformeJs(Transformer):
|
||||
for _idx, _item in enumerate(item):
|
||||
try:
|
||||
self._logger.debug(
|
||||
f"\t\titem[{idx}]->{_idx}: {ast.dump(_item)}")
|
||||
f"\t\titem[{idx}]->{_idx}: {ast.dump(_item)} - '{_item}'")
|
||||
except:
|
||||
self._logger.debug(
|
||||
f"\t\titem[{idx}]->{_idx}: {_item}")
|
||||
else:
|
||||
self._logger.debug(
|
||||
f"\t\titem[{idx}]: {ast.dump(item)}")
|
||||
f"\t\titem[{idx}]: {ast.dump(item)} - '{_item}'")
|
||||
except:
|
||||
self._logger.debug(
|
||||
f"\t\titem[{idx}]: {item}")
|
||||
@ -351,6 +367,7 @@ class CodeTransformeJs(Transformer):
|
||||
def start(self, items):
|
||||
self._log("start", items)
|
||||
body = self.body(items)
|
||||
body.insert(0, define_dotted_dict("ast"))
|
||||
return _ast.Module(body=body)
|
||||
|
||||
def return_statement(self, items):
|
||||
@ -472,13 +489,21 @@ class CodeTransformeJs(Transformer):
|
||||
)
|
||||
|
||||
def instanceof(self, items):
|
||||
return _ast.Call(
|
||||
func=_ast.Name(id='type'),
|
||||
args=[
|
||||
items[0]
|
||||
|
||||
ret = self._op(
|
||||
[
|
||||
_ast.Call(
|
||||
func=_ast.Name(id='type'),
|
||||
args=[
|
||||
items[0],
|
||||
],
|
||||
keywords=[]
|
||||
),
|
||||
items[1]
|
||||
],
|
||||
keywords=[]
|
||||
self.bool_op_is([])
|
||||
)
|
||||
return ret
|
||||
|
||||
def delete_stmt(self, items):
|
||||
return _ast.Delete(
|
||||
@ -584,6 +609,9 @@ class CodeTransformeJs(Transformer):
|
||||
def bool_op_in(self, items):
|
||||
return _ast.In()
|
||||
|
||||
def bool_op_is(self, items):
|
||||
return _ast.Is()
|
||||
|
||||
def list(self, items):
|
||||
if items[0] is not None:
|
||||
|
||||
@ -639,11 +667,31 @@ class CodeTransformeJs(Transformer):
|
||||
keys += item["keys"]
|
||||
values += item["values"]
|
||||
|
||||
ret = _ast.Dict(
|
||||
keys=keys,
|
||||
values=self._adapt_items(values),
|
||||
ctx=ast.Load()
|
||||
)
|
||||
args = self.func_args([])
|
||||
args.args= [
|
||||
_ast.Dict(
|
||||
keys=keys,
|
||||
values=self._adapt_items(values),
|
||||
ctx=ast.Load()
|
||||
)
|
||||
]
|
||||
|
||||
ret = self.new_class([
|
||||
define_dotted_dict(),
|
||||
[
|
||||
_ast.Dict(
|
||||
keys=keys,
|
||||
values=self._adapt_items(values),
|
||||
ctx=ast.Load()
|
||||
)
|
||||
]
|
||||
])
|
||||
|
||||
# ret = _ast.Dict(
|
||||
# keys=keys,
|
||||
# values=self._adapt_items(values),
|
||||
# ctx=ast.Load()
|
||||
# )
|
||||
|
||||
return ret
|
||||
|
||||
@ -940,7 +988,7 @@ class CodeTransformeJs(Transformer):
|
||||
def reassign(self, items):
|
||||
return self.declare_var([None, None, items[0], items[1]])
|
||||
|
||||
def _function(self, items, type=None):
|
||||
def _function(self, items, func_type=None):
|
||||
""" Uses Rule = [export] "function" [id] "(" [func_args] ")" func_body
|
||||
|
||||
Args:
|
||||
@ -951,7 +999,7 @@ class CodeTransformeJs(Transformer):
|
||||
_type_: _description_
|
||||
"""
|
||||
|
||||
_constructor = _ast.AsyncFunctionDef if type == "async" else _ast.FunctionDef
|
||||
_constructor = _ast.AsyncFunctionDef if func_type == "async" else _ast.FunctionDef
|
||||
|
||||
(export, name, func_args, body) = items
|
||||
|
||||
@ -977,9 +1025,9 @@ class CodeTransformeJs(Transformer):
|
||||
ret = _constructor(** kwargs)
|
||||
|
||||
# Register the Function.
|
||||
self._anonymous_func_to_ids[ret] = name
|
||||
self._ids_to_anonymous_func[name.id] = ret
|
||||
# self._anonymous_func_tree[ret] = name
|
||||
def_name = _ast.Name(id = "__definition_of__"+name.id)
|
||||
self._anonymous_func_to_ids[ret] = def_name
|
||||
self._ids_to_anonymous_func[def_name] = ret
|
||||
|
||||
return ret
|
||||
|
||||
@ -991,11 +1039,11 @@ class CodeTransformeJs(Transformer):
|
||||
def async_function(self, items):
|
||||
self._log("async_function", items)
|
||||
|
||||
return self._function(items, "async")
|
||||
return self._function(items, func_type="async")
|
||||
|
||||
def _arrow_function(self, items, type=None):
|
||||
def _arrow_function(self, items, func_type=None):
|
||||
self._log("_arrow_function", items)
|
||||
return self._function([None, None, *items], type)
|
||||
return self._function([None, None, *items], func_type=func_type)
|
||||
|
||||
def arrow_function(self, items):
|
||||
self._log("arrow_function", items)
|
||||
@ -1010,7 +1058,7 @@ class CodeTransformeJs(Transformer):
|
||||
def async_arrow_function(self, items):
|
||||
self._log("async_arrow_function", items)
|
||||
|
||||
return self._arrow_function(items, "async")
|
||||
return self._arrow_function(items, func_type="async")
|
||||
|
||||
def func_args(self, items):
|
||||
ret = {
|
||||
@ -1032,7 +1080,12 @@ class CodeTransformeJs(Transformer):
|
||||
else:
|
||||
ret["vararg"] = ret["vararg"][0]
|
||||
|
||||
return _ast.arguments(**ret)
|
||||
|
||||
args = _ast.arguments(**ret)
|
||||
|
||||
self._add_to_tree(args, ret["args"] + ret["defaults"])
|
||||
|
||||
return args
|
||||
|
||||
def default_func_arg(self, items):
|
||||
|
||||
@ -1112,6 +1165,8 @@ class CodeTransformeJs(Transformer):
|
||||
keywords=[]
|
||||
)
|
||||
|
||||
# self._add_to_tree(ret, args)
|
||||
|
||||
return ret
|
||||
|
||||
def rest_call_arg(self, items):
|
||||
@ -1216,7 +1271,7 @@ class CodeTransformeJs(Transformer):
|
||||
test = items[0]
|
||||
body = items[1]
|
||||
elifs = items[2]
|
||||
else_body = items[3] if items[3] is not None else []
|
||||
else_body = self._adapt_body(items[3]) if items[3] is not None else []
|
||||
|
||||
inclused_elif = elifs is not None
|
||||
|
||||
@ -1405,7 +1460,7 @@ class CodeTransformeJs(Transformer):
|
||||
args=[], defaults=[])
|
||||
args.args.insert(0, _ast.arg(arg='self', annotation=None))
|
||||
|
||||
return _ast.FunctionDef(name='__init__', args=args, body=body, decorator_list=[])
|
||||
return _ast.FunctionDef(name='__init__', args=args, body= self._adapt_body(body), decorator_list=[])
|
||||
|
||||
def getter(self, items):
|
||||
# Rule = id "(" [func_args] ")" func_body
|
||||
@ -1452,7 +1507,7 @@ class CodeTransformeJs(Transformer):
|
||||
|
||||
def async_method(self, items):
|
||||
# Rule = "async" id "(" [func_args] ")" func_body
|
||||
ret = self._function([None, *items], "async")
|
||||
ret = self._function([None, *items], func_type="async")
|
||||
|
||||
method_args = [_ast.arg(arg='self', annotation=None)]
|
||||
method_args.extend(ret.args.args)
|
||||
@ -1461,12 +1516,16 @@ class CodeTransformeJs(Transformer):
|
||||
return ret
|
||||
|
||||
|
||||
def transform(tree, debug):
|
||||
def transform(tree, debug, to_snake_case):
|
||||
transformer = CodeTransformeJs(
|
||||
True, logging.DEBUG if debug else logging.INFO)
|
||||
level = logging.DEBUG if debug else logging.INFO,
|
||||
to_snake_case = to_snake_case
|
||||
)
|
||||
|
||||
program = transformer.transform(tree)
|
||||
|
||||
code = astor.to_source(program)
|
||||
|
||||
if debug:
|
||||
print(ast.dump(program, indent=2))
|
||||
|
||||
@ -1478,6 +1537,6 @@ def transform(tree, debug):
|
||||
print("-"*l)
|
||||
print("\n"*2)
|
||||
|
||||
code = astor.to_source(program)
|
||||
print(code)
|
||||
|
||||
return code
|
||||
|
@ -3,7 +3,7 @@ import os
|
||||
import re
|
||||
import multiprocessing as mp
|
||||
|
||||
from . import get_logger, ts, js, post_process
|
||||
from . import get_logger, ts, js, post_process, to_snake_case
|
||||
|
||||
MAX_CPU = mp.cpu_count()
|
||||
|
||||
@ -29,18 +29,19 @@ def worker(opt):
|
||||
|
||||
return parse(func[type].get_parser(), *opt)
|
||||
|
||||
def parse(parser, type, logger, input_path, output_path, name, path_to_file, dir_path, debug):
|
||||
def parse(parser, type, logger, input_path, output_path, name, path_to_file, dir_path, debug, convert_snake_case):
|
||||
""" Function to generate the python-code
|
||||
|
||||
Args:
|
||||
parser (_type_): The Parser to use (js/ts)
|
||||
logger (_type_): The Logger
|
||||
input_path (_type_): path of the folder to readin
|
||||
output_path (_type_): main path of the output
|
||||
name (_type_): name of the file
|
||||
path_to_file (_type_): path to the file
|
||||
dir_path (_type_): directory of the file
|
||||
debug (_type_): Flag to enable debugging
|
||||
parser: The Parser to use (js/ts)
|
||||
logger (logging.logger): The Logger
|
||||
input_path (str): path of the folder to readin
|
||||
output_path (str): main path of the output
|
||||
name (str): name of the file
|
||||
path_to_file (str): path to the file
|
||||
dir_path (str): directory of the file
|
||||
debug (boolean): Flag to enable debugging
|
||||
convert_snake_case (boolean): Flag to enable converting methods and names to ids.
|
||||
|
||||
Returns:
|
||||
(
|
||||
@ -59,8 +60,13 @@ def parse(parser, type, logger, input_path, output_path, name, path_to_file, dir
|
||||
try:
|
||||
|
||||
python_name = name.replace(".ts", ".py").replace(".js", ".py")
|
||||
|
||||
rel_path = dir_path[len(input_path) + 1:]
|
||||
|
||||
if convert_snake_case:
|
||||
python_name = to_snake_case(python_name)
|
||||
rel_path = to_snake_case(rel_path)
|
||||
|
||||
logger.debug(f"determined the following rel-path = {rel_path}")
|
||||
|
||||
pytho_path_to_file = os.path.join(output_path,rel_path,python_name)
|
||||
@ -68,7 +74,8 @@ def parse(parser, type, logger, input_path, output_path, name, path_to_file, dir
|
||||
try:
|
||||
code = func[type].transform(
|
||||
parser.parse(open(path_to_file, encoding="utf-8").read()),
|
||||
debug
|
||||
debug,
|
||||
convert_snake_case
|
||||
)
|
||||
|
||||
logger.debug(f"converted {path_to_file}")
|
||||
@ -136,6 +143,8 @@ def main():
|
||||
help='Shows debug related output')
|
||||
parser.add_argument('--cores', type=int, default=MAX_CPU, dest='cores',
|
||||
help='The Amount of cores, which must be use')
|
||||
parser.add_argument('--convert_snake_case', dest='convert_snake_case', action='store_true',
|
||||
help='Converts the names to snake-case')
|
||||
|
||||
# Create a Logger:
|
||||
logger = get_logger("nope-py-prepare")
|
||||
@ -215,10 +224,10 @@ def main():
|
||||
file_name, # Name of the File
|
||||
path_to_file, # Path to the File
|
||||
dir_path, # Path of the Directory.
|
||||
args.debug
|
||||
args.debug,
|
||||
args.convert_snake_case
|
||||
) for file_name, path_to_file, dir_path in typescript_files
|
||||
]
|
||||
)
|
||||
])
|
||||
# Close the Pool
|
||||
pool.close()
|
||||
# Wait to finish all.
|
||||
|
@ -11,16 +11,19 @@ replacers = {
|
||||
"const _this = this;": "",
|
||||
"_this": "self",
|
||||
"this": "self",
|
||||
"Set": "set",
|
||||
"Map": "dict",
|
||||
" Set": " set",
|
||||
" Map": " dict",
|
||||
"toLowerCase": "lower",
|
||||
"toUpperCase": "upper",
|
||||
".push(": ".append(",
|
||||
".indexOf(": ".index(",
|
||||
"Array.from": "list",
|
||||
"null": "None",
|
||||
'"null"': "None",
|
||||
'"undefined"': "None"
|
||||
|
||||
'"undefined"': "None",
|
||||
'undefined': "None",
|
||||
'self = self': "",
|
||||
"__definition_of__": ""
|
||||
}
|
||||
|
||||
def post_process(code: str) -> str:
|
||||
|
@ -901,7 +901,7 @@ class DebuggedCodeTransformeTs(Transformer):
|
||||
raise KeyError(f"'{__name}' has not been found!")
|
||||
|
||||
|
||||
def transform(tree, debug):
|
||||
def transform(tree, debug, to_snake_case):
|
||||
transformer = CodeTransformeTs(
|
||||
True, logging.DEBUG if debug else logging.INFO)
|
||||
program = transformer.transform(tree)
|
||||
|
Loading…
Reference in New Issue
Block a user