|
- import ast
- import os
- import tokenize
-
- import asttokens
-
- # 返回asttokens, 该对象含有文件文本内容,抽象语法树
- from visitor import CallNameTransformer
-
-
- def asttokens_file(file_path):
- with tokenize.open(file_path) as f:
- text = f.read()
- atok = asttokens.ASTTokens(text, parse=True, filename=file_path)
- return atok
-
-
- #
- # def get_node_name(node):
- # if isinstance(node, ast.Name):
- # name = node.id
- # return name
- # elif isinstance(node, ast.Constant):
- # name = node.value
- # return str(name)
- # elif isinstance((tmp := node), ast.Attribute):
- # attr = tmp.attr
- # if isinstance(tmp.value, (ast.Constant, ast.Attribute, ast.Name, ast.Call, ast.Subscript, ast.Slice)):
- # name = get_node_name(tmp.value)
- # name = name + '.' + attr
- # return name
- # elif isinstance((tmp := node), ast.Call):
- # if isinstance(tmp.func, (ast.Constant, ast.Attribute, ast.Name, ast.Call, ast.Subscript, ast.Slice)):
- # name = get_node_name(tmp.func) + '()'
- # return name
- # elif isinstance((tmp := node), ast.Subscript):
- # value_name = ''
- # slice_name = ''
- # if isinstance(tmp.value, (ast.Constant, ast.Attribute, ast.Name, ast.Call, ast.Subscript, ast.Slice)):
- # value_name = get_node_name(tmp.value)
- # if isinstance(tmp.value, (ast.Constant, ast.Attribute, ast.Name, ast.Call, ast.Subscript, ast.Slice)):
- # slice_name = get_node_name(tmp.slice)
- # name = value_name + '[' + slice_name + ']'
- # return name
- # elif isinstance((tmp := node), ast.Slice):
- # lower_name = ''
- # upper_name = ''
- # if tmp.lower is not None and isinstance(tmp.lower, (ast.Constant, ast.Attribute, ast.Name, ast.Call, ast.Subscript, ast.Slice)):
- # lower_name = get_node_name(tmp.lower)
- # if tmp.upper is not None and isinstance(tmp.upper, (ast.Constant, ast.Attribute, ast.Name, ast.Call, ast.Subscript, ast.Slice)):
- # upper_name = get_node_name(tmp.upper)
- # name = lower_name + ':' + upper_name
- # return name
- #
- # return ''
- def get_attribute_name(node):
- if isinstance(node, ast.Name):
- name = node.id
- return name
- elif isinstance((tmp := node), ast.Attribute):
- attr = tmp.attr
- if isinstance(tmp.value, (ast.Attribute, ast.Name)):
- name = get_attribute_name(tmp.value)
- if name == '':
- return attr,
- else:
- name = name + '.' + attr
- return name
- else:
- return attr
- return ''
-
-
- def get_project_package(name, path_list):
- relative_path = name.replace('.', '\\')
- for path in path_list:
- abs_path = os.path.join(path, relative_path)
- if os.path.isdir(abs_path):
- package_conf_path = abs_path + r'\__init__.py'
- if os.path.isfile(package_conf_path):
- return package_conf_path
- return None
-
-
- # 判断项目目录下是否存在该模块文件
- def is_module(name, path_list):
- relative_path = name.replace('.', '\\')
- for path in path_list:
- abs_path = os.path.join(path, relative_path)
- abs_path = abs_path + r'.py'
- if os.path.isfile(abs_path):
- return True
- return False
-
-
- # 创建以name为名字的ast.Attribute节点
- def create_attribute_node(name):
- name_list = name.split('.')
- name_node = ast.Name(id=name_list[0])
- new_node = ast.Attribute(value=name_node, attr=name_list[1])
- i = 2
- while i < len(name_list):
- new_node = ast.Attribute(value=new_node, attr=name_list[i])
- i = i + 1
-
- return new_node
-
-
- # 得到path在项目路径的下的相对路径:
- def relative_path(path, project_path):
- if project_path in path:
- relative_path = path.replace(project_path, '')
- return relative_path[1:]
- else:
- print('relative_path:error')
-
-
- def change_relative_module(relative_module, relative_path):
- relative_path = relative_path.replace('\\', '.')
- if relative_module == '.':
- return relative_path
- elif relative_module == '..':
- return relative_path.rsplit('.', 1)[0]
- elif relative_module.startswith('.'):
- return relative_path + relative_module
- elif relative_module.startswith('..'):
- return relative_path.rsplit('.', 1)[0] + relative_module.replace('..', '.')
-
-
- def traversal(adj, node):
- from collections import deque
- todo = deque([node])
- while todo:
- node = todo.popleft()
-
- todo.extend(adj[node].keys())
- yield node
-
-
- def get_token_axis(token):
- return token.start, token.end
|