|
|
@@ -19,6 +19,7 @@ |
|
|
import ast |
|
|
import ast |
|
|
import types |
|
|
import types |
|
|
import inspect |
|
|
import inspect |
|
|
|
|
|
import hashlib |
|
|
from textwrap import dedent |
|
|
from textwrap import dedent |
|
|
from dataclasses import is_dataclass |
|
|
from dataclasses import is_dataclass |
|
|
import asttokens |
|
|
import asttokens |
|
|
@@ -319,7 +320,6 @@ def get_dataclass_methods(cls): |
|
|
if isinstance(getattr(cls, name), (types.FunctionType,))} |
|
|
if isinstance(getattr(cls, name), (types.FunctionType,))} |
|
|
return methods |
|
|
return methods |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Parser: |
|
|
class Parser: |
|
|
""" |
|
|
""" |
|
|
Parser python code to ast tree. |
|
|
Parser python code to ast tree. |
|
|
@@ -327,7 +327,10 @@ class Parser: |
|
|
Args: |
|
|
Args: |
|
|
fn(FunctionType/MethodType): Need parse object instance. |
|
|
fn(FunctionType/MethodType): Need parse object instance. |
|
|
parse_method(ExtendInfoOfParseObj): Extend information for parse the function. |
|
|
parse_method(ExtendInfoOfParseObj): Extend information for parse the function. |
|
|
|
|
|
ast_cache: Dictionary for caching ast tree. |
|
|
""" |
|
|
""" |
|
|
|
|
|
ast_cache = {} |
|
|
|
|
|
|
|
|
def __init__(self, fn: (types.FunctionType, types.MethodType), parse_method=None) -> None: |
|
|
def __init__(self, fn: (types.FunctionType, types.MethodType), parse_method=None) -> None: |
|
|
self.fn = fn |
|
|
self.fn = fn |
|
|
self.parse_method = parse_method |
|
|
self.parse_method = parse_method |
|
|
@@ -342,17 +345,31 @@ class Parser: |
|
|
self.function_name = fn.__name__ |
|
|
self.function_name = fn.__name__ |
|
|
self.col_offset = 0 |
|
|
self.col_offset = 0 |
|
|
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
|
def get_cache(cls, key): |
|
|
|
|
|
"""Get the value of the ast_cache dictionary""" |
|
|
|
|
|
return cls.ast_cache.get(key) |
|
|
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
|
def insert_cache(cls, key, value): |
|
|
|
|
|
"""Insert elements to the ast_cache dictionary""" |
|
|
|
|
|
cls.ast_cache[key] = value |
|
|
|
|
|
|
|
|
def parse(self): |
|
|
def parse(self): |
|
|
"""Parse the function or method.""" |
|
|
"""Parse the function or method.""" |
|
|
logger.debug("fn = %r", self.fn) |
|
|
logger.debug("fn = %r", self.fn) |
|
|
tree = None |
|
|
tree = None |
|
|
if isinstance(self.fn, (types.FunctionType, types.MethodType)): |
|
|
if isinstance(self.fn, (types.FunctionType, types.MethodType)): |
|
|
original_src = inspect.getsource(self.fn) |
|
|
original_src = inspect.getsource(self.fn) |
|
|
src = dedent(original_src) |
|
|
|
|
|
self.col_offset = \ |
|
|
|
|
|
len(original_src.split('\n')[0]) - len(src.split('\n')[0]) |
|
|
|
|
|
logger.debug("get source = %s", src) |
|
|
|
|
|
tree = asttokens.ASTTokens(src, parse=True).tree |
|
|
|
|
|
|
|
|
hexstr = hashlib.sha256(original_src.encode()).hexdigest() |
|
|
|
|
|
tree = Parser.get_cache(hexstr) |
|
|
|
|
|
if not tree: |
|
|
|
|
|
src = dedent(original_src) |
|
|
|
|
|
self.col_offset = \ |
|
|
|
|
|
len(original_src.split('\n')[0]) - len(src.split('\n')[0]) |
|
|
|
|
|
logger.debug("get source = %s", src) |
|
|
|
|
|
tree = asttokens.ASTTokens(src, parse=True).tree |
|
|
|
|
|
Parser.insert_cache(hexstr, tree) |
|
|
else: |
|
|
else: |
|
|
logger.error("Fn type is invalid") |
|
|
logger.error("Fn type is invalid") |
|
|
return tree |
|
|
return tree |
|
|
|