11
22from typing import Dict , List , Tuple , Type
3- from inspect import getsource , unwrap
43from ast import (
54 NodeVisitor , arg , expr ,
65 FunctionDef , Assign , AnnAssign ,
76 Attribute , Name , Subscript , get_source_segment
87)
98from collections import namedtuple
10- from textwrap import dedent
11- from importlib import import_module
129
1310from py2puml .domain .umlclass import UmlAttribute , UmlMethod
1411from py2puml .domain .umlrelation import UmlRelation , RelType
1512from py2puml .parsing .compoundtypesplitter import CompoundTypeSplitter , SPLITTING_CHARACTERS
16- from py2puml .parsing .moduleresolver import ModuleResolver , NamespacedType
13+ from py2puml .parsing .moduleresolver import ModuleResolver
1714
1815Variable = namedtuple ('Variable' , ['id' , 'type_expr' ])
1916
@@ -35,8 +32,7 @@ def visit_arg(self, node: arg):
3532 if self .class_self_id is None and not self .skip_self :
3633 self .class_self_id = variable .id
3734 # other arguments are constructor parameters
38- else :
39- self .variables .append (variable )
35+ self .variables .append (variable )
4036
4137
4238class AssignedVariablesCollector (NodeVisitor ):
@@ -80,6 +76,21 @@ def visit_FunctionDef(self, node: FunctionDef):
8076 self .uml_methods .append (method_visitor .uml_method )
8177
8278
79+ class ReturnTypeVisitor (NodeVisitor ):
80+
81+ def __init__ (self , * args , ** kwargs ):
82+ super ().__init__ (* args , ** kwargs )
83+
84+ def visit_Name (self , node ):
85+ return node .id
86+
87+ def visit_Constant (self , node ):
88+ return node .value
89+
90+ def visit_Subscript (self , node ):
91+ return node .value .id
92+
93+
8394class MethodVisitor (NodeVisitor ):
8495 """
8596 Node visitor subclass used to walk the abstract syntax tree of a method class and identify method arguments.
@@ -90,12 +101,8 @@ class MethodVisitor(NodeVisitor):
90101 def __init__ (self , * args , ** kwargs ):
91102 super ().__init__ (* args , ** kwargs )
92103 self .variables_namespace : List [Variable ] = []
93- self .class_self_id : str
94104 self .uml_method : UmlMethod
95105
96- def generic_visit (self , node ):
97- NodeVisitor .generic_visit (self , node )
98-
99106 def visit_FunctionDef (self , node : FunctionDef ):
100107 decorators = [decorator .id for decorator in node .decorator_list ]
101108 is_static = 'staticmethod' in decorators
@@ -104,20 +111,23 @@ def visit_FunctionDef(self, node: FunctionDef):
104111 variables_collector .visit (node )
105112 self .variables_namespace = variables_collector .variables
106113
107- if node .name == '__init__' :
108- self .class_self_id : str = variables_collector .class_self_id
109- self .generic_visit (node ) #Only visit child nodes for constructor
110-
111114 self .uml_method = UmlMethod (name = node .name , is_static = is_static , is_class = is_class )
115+
112116 for argument in variables_collector .variables :
117+ if argument .id == variables_collector .class_self_id :
118+ self .uml_method .arguments [argument .id ] = None
113119 if argument .type_expr :
114120 if hasattr (argument .type_expr , 'id' ):
115121 self .uml_method .arguments [argument .id ] = argument .type_expr .id
116122 else :
117- self .uml_method .arguments [argument .id ] = f'SUBscript { argument .type_expr .value .id } '
123+ self .uml_method .arguments [argument .id ] = f'Subscript { argument .type_expr .value .id } ' #FIXME
118124 else :
119125 self .uml_method .arguments [argument .id ] = None
120126
127+ if node .returns is not None :
128+ return_visitor = ReturnTypeVisitor ()
129+ self .uml_method .return_type = return_visitor .visit (node .returns )
130+
121131
122132class ConstructorVisitor (NodeVisitor ):
123133 '''
0 commit comments