def visit_common_function_def( self, node: Union[ast.FunctionDef, ast.AsyncFunctionDef]) -> Any: r = create_range_from_ast_node(node) self.function = FunctionDeclaration( node.name, self.scope_manager.get_qualified_name_from_current_scope( node.name, r.start_position.line), FilePosition(self.current_file, r), [], "") for call in reversed(self.current_function_calls): if call.name == self.function.name and call.file_position == self.function.file_position: return # self.scope_manager.append_function_to_current_scope(self.function) self.current_function_declaration.append(self.function) def action(): self.collect_parameters(node) self.generic_visit(node) self.scope_manager.with_scope( FunctionScope( node.name, self.scope_manager.get_qualified_scope_name_from_current_scope( ), FilePosition.get_empty_file_position()), action) del self.current_function_declaration[-1]
def append_class(self, node: ast.ClassDef): self.class_list.append(len(self.classes)) preprocessed_class = PreprocessedClass( node.name, FilePosition(self.path, create_range_from_ast_node(node))) self.classes.append(preprocessed_class) self.handle_nested_class(node, preprocessed_class) for member in node.body: if isinstance(member, (ast.FunctionDef, ast.AsyncFunctionDef)): self.append_method( member, FilePosition(self.path, create_range_from_ast_node(member))) elif isinstance(member, ast.Assign): self.append_attribute( member, FilePosition(self.path, create_range_from_ast_node(member))) elif isinstance(member, ast.ClassDef): self.append_nested_class(preprocessed_class, member) elif isinstance(member, ast.Pass): pass elif isinstance(member, ast.Expr) and hasattr(member, 'value') and isinstance(member.value, ast.Constant) \ and hasattr(member.value, "value") and isinstance(member.value.value, str): pass # documentation comment else: pass
def __init__(self): file_position = FilePosition.get_empty_file_position() qualified_name = "builtins.function." + self.get_name() super().__init__(self.get_name(), qualified_name, file_position, [], "", self.get_type()) if self.get_override() is None: self.override = [] else: self.override: List[str] = self.get_override()
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> Any: if self.depth == 0: self.preprocessed_functions.add( PreprocessedFunction( node.name, FilePosition(self.path, create_range_from_ast_node(node)), node)) self.depth += 1 self.generic_visit(node) self.depth -= 1
def visit_Assign(self, node: ast.Assign) -> Any: if self.depth == 0: for target in node.targets: if isinstance(target, ast.Name): self.preprocessed_variables.add( PreprocessedVariable( target.id, FilePosition(self.path, create_range_from_ast_node(node)))) else: pass # print("...")
def _(self, node: ast.Call): if hasattr(node.func, 'id'): # TODO: check if builtin class ctor-s are not hidden by other (custom) functions/classes # TODO: no args check (builtin is not hidden + correct code -> should not be a problem) built_in_function = get_built_in_function(node.func.id) if built_in_function is not None: return built_in_function elif node.func.id == 'TypeVar': return Type() return self.get_member_access_type(MemberAccessCollector(node), FilePosition(self.scope_manager.current_file, create_range_from_ast_node(node)))
def __init__(self, current_file: PurePath, import_finder: ImportFinder, persistence: ModelPersistence, scopes: Optional[List[Scope]] = None): self.current_file = current_file self.import_finder = import_finder if scopes is None: self.scopes: List[Scope] = [ GlobalScope( self.get_qualified_scope_name_from_current_scope([]), FilePosition(current_file, Range.get_empty_range())) ] else: self.scopes = scopes self.persistence: ModelPersistence = persistence self.placeholder_function_declaration_cache = PlaceholderFunctionDeclarationCache( ) self.persist_symbols: int = 0
def collect_parameters( self, node: Union[ast.FunctionDef, ast.AsyncFunctionDef]) -> None: args_with_default = [] for i in range(0, len(node.args.args)): if i < len(node.args.defaults): default = node.args.defaults[-(i + 1)] else: default = None args_with_default.append((node.args.args[-(i + 1)], default)) arg_idx = 0 for param in reversed(args_with_default): r = create_range_from_ast_node(node) qualified_name = self.scope_manager.\ get_qualified_name_from_current_scope(param[0].arg, r.start_position.line) new_variable = VariableDeclaration( param[0].arg, qualified_name, FilePosition(self.current_file, r)) if param[0].arg == 'self' and self.scope_manager.is_current_scope_method() and \ node.args.args[0] is param[0]: new_variable.type.add( self.scope_manager.get_current_class_declaration()) else: # has kw -> has arg -> default keyword = [k for k in self.arguments if k[1] == param[0].arg] if len(keyword) == 0: if arg_idx < len(self.arguments): new_variable.type.update( self.type_deduction.get_current_type( {self.arguments[arg_idx][0]})) arg_idx += 1 elif param[1] is not None: new_variable.type.update( self.type_deduction.get_current_type( self.type_deduction.deduct_type(param[1]))) elif len(keyword) == 1: new_variable.type.update( self.type_deduction.get_current_type({keyword[0][0]})) else: assert False self.scope_manager.append_variable_to_current_scope(new_variable)
def __init__(self): super().__init__(self.get_name(), "builtins.type." + self.get_name(), FilePosition.get_empty_file_position())
def visit_Assign(self, node: ast.Assign): self.append_attribute( node, FilePosition(self.path, create_range_from_ast_node(node))) self.generic_visit(node)
def _(self, node: ast.Attribute): return self.get_member_access_type(MemberAccessCollector(node), FilePosition(self.scope_manager.current_file, create_range_from_ast_node(node)))