@@ -112,7 +112,8 @@ class PythonToPythonJS(NodeVisitor):
112112 def __init__ (self , module = None , module_path = None ):
113113 super (PythonToPythonJS , self ).__init__ ()
114114 self ._classes = dict () ## class name : [method names]
115- self ._inline_classes = dict () ## class name : [attribute names]
115+ self ._instance_attributes = dict () ## class name : [attribute names]
116+ self ._class_attributes = dict ()
116117 self ._catch_attributes = None
117118 self ._names = set () ## not used?
118119 self ._instances = dict () ## instance name : class name
@@ -134,14 +135,17 @@ def get_typedef(self, instance=None, class_name=None):
134135 name = class_name ,
135136 methods = self ._classes [ class_name ],
136137 properties = self ._decorator_class_props [ class_name ],
138+ attributes = self ._instance_attributes [ class_name ],
139+ class_attributes = self ._class_attributes [ class_name ],
137140 )
138141 return typedef
139142
140143 def save_module (self ):
141144 if self ._module and self ._module_path :
142145 a = dict (
143146 classes = self ._classes ,
144- inline_classes = self ._inline_classes ,
147+ instance_attributes = self ._instance_attributes ,
148+ class_attributes = self ._class_attributes ,
145149 decorator_class_props = self ._decorator_class_props ,
146150 function_return_types = self ._function_return_types ,
147151 )
@@ -157,13 +161,14 @@ def visit_ImportFrom(self, node):
157161 f = open ( os .path .join (self ._module_path , node .module + '.module' ), 'rb' )
158162 a = pickle .load ( f ); f .close ()
159163 self ._classes .update ( a ['classes' ] )
160- self ._inline_classes .update ( a ['inline_classes' ] )
164+ self ._class_attributes .update ( a ['class_attributes' ] )
165+ self ._instance_attributes .update ( a ['instance_attributes' ] )
161166 self ._decorator_class_props .update ( a ['decorator_class_props' ] )
162167 self ._function_return_types .update ( a ['function_return_types' ] )
163168
164169 def visit_Assert (self , node ):
165170 ## hijacking "assert isinstance(a,A)" as a type system ##
166- if isinstance ( node .test , Call ) and node .test .func .id == 'isinstance' :
171+ if isinstance ( node .test , Call ) and isinstance ( node . test . func , Name ) and node .test .func .id == 'isinstance' :
167172 a ,b = node .test .args
168173 if b .id in self ._classes :
169174 self ._instances [ a .id ] = b .id
@@ -217,14 +222,19 @@ def _gen_getattr_helper(self, class_name, func_name):
217222 def visit_ClassDef (self , node ):
218223 name = node .name
219224 self ._classes [ name ] = list () ## method names
225+ self ._class_attributes [ name ] = set ()
220226 self ._catch_attributes = None
221227 self ._decorator_properties = dict () ## property names : {'get':func, 'set':func}
222228 self ._decorator_class_props [ name ] = self ._decorator_properties
223229 self ._instances [ 'self' ] = name
224230
225- for dec in node .decorator_list :
226- if isinstance (dec , Name ) and dec .id == 'inline' :
227- self ._catch_attributes = set ()
231+ #for dec in node.decorator_list:
232+ # if isinstance(dec, Name) and dec.id == 'inline':
233+ # self._catch_attributes = set()
234+ ## always catch attributes ##
235+ self ._catch_attributes = set ()
236+ self ._instance_attributes [ name ] = self ._catch_attributes
237+
228238
229239 writer .write ('var(%s, __%s_attrs, __%s_parents)' % (name , name , name ))
230240 writer .write ('__%s_attrs = JSObject()' % name )
@@ -246,17 +256,20 @@ def visit_ClassDef(self, node):
246256 else :
247257 writer .write ('__%s_attrs["%s"] = %s' % (name , item_name , item .name ))
248258
249- if item_name == '__getattr__' :
250- writer .write ( self ._gen_getattr_helper (name , item .name ) )
259+ # if item_name == '__getattr__':
260+ # writer.write( self._gen_getattr_helper(name, item.name) )
251261
252- elif isinstance (item , Assign ):
262+ elif isinstance (item , Assign ) and isinstance ( item . targets [ 0 ], Name ) :
253263 item_name = item .targets [0 ].id
254- item .targets [0 ].id = '__%s_%s' % (name . id , item_name )
264+ item .targets [0 ].id = '__%s_%s' % (name , item_name )
255265 self .visit (item ) # this will output the code for the assign
256- writer .write ('%s_attrs["%s"] = %s' % (name , item_name , item .targets [0 ].id ))
266+ writer .write ('__%s_attrs["%s"] = %s' % (name , item_name , item .targets [0 ].id ))
267+ self ._class_attributes [ name ].add ( item_name ) ## should this come before self.visit(item) ??
268+ else :
269+ raise NotImplementedError
257270
258- if self ._catch_attributes :
259- self ._inline_classes [ name ] = self ._catch_attributes
271+ # if self._catch_attributes:
272+ # self._instance_attributes [ name ] = self._catch_attributes
260273
261274 self ._catch_attributes = None
262275 self ._decorator_properties = None
@@ -407,6 +420,13 @@ def visit_Attribute(self, node):
407420 if getter in self ._function_return_types :
408421 node .returns_type = self ._function_return_types [getter ]
409422 return '%s( [%s] )' % (getter , node_value )
423+ elif node .attr in typedef .class_attributes :
424+ return "%s['__class__']['__dict__']['%s']" % (node_value , node .attr )
425+ elif node .attr in typedef .attributes :
426+ return "%s['__dict__']['%s']" % (node_value , node .attr )
427+ elif '__getattr__' in typedef .methods :
428+ func = typedef .get_pythonjs_function_name ( '__getattr__' )
429+ return '%s([%s, "%s"])' % (func , node_value , node .attr )
410430 else :
411431 return 'get_attribute(%s, "%s")' % (node_value , node .attr )
412432 else :
@@ -418,8 +438,8 @@ def visit_Attribute_OLD(self, node):
418438 if name in self ._instances : ## support '.' operator overloading
419439 klass = self ._instances [ name ]
420440 if '__getattr__' in self ._classes [ klass ]:
421- if klass in self ._inline_classes : ## static attribute
422- if node .attr in self ._inline_classes [klass ]:
441+ if klass in self ._instance_attributes : ## static attribute
442+ if node .attr in self ._instance_attributes [klass ]:
423443 #return '''JS('%s.__dict__["%s"]')''' %(name, node.attr) ## this is not ClosureCompiler compatible
424444 return '''JS('%s["__dict__"]["%s"]')''' % (name , node .attr )
425445 elif node .attr in self ._classes [ klass ]: ## method
@@ -433,8 +453,8 @@ def visit_Attribute_OLD(self, node):
433453 else : ## dynamic python style
434454 return '__%s____getattr_helper( [%s, "%s"] )' % (klass , name , node .attr )
435455 else :
436- if klass in self ._inline_classes : ## static attribute
437- if node .attr in self ._inline_classes [klass ]:
456+ if klass in self ._instance_attributes : ## static attribute
457+ if node .attr in self ._instance_attributes [klass ]:
438458 return '''JS('%s["__dict__"]["%s"]')''' % (name , node .attr )
439459 elif node .attr in self ._classes [ klass ]: ## method
440460 return '''JS('__%s_attrs["%s"]')''' % (klass , node .attr )
0 commit comments