Skip to content

Commit 3262d08

Browse files
author
hartsantler
committed
refactoring getter/setter @Property so that nested lookups can work, ie: camera.position.x=1
1 parent af8c1e5 commit 3262d08

1 file changed

Lines changed: 71 additions & 22 deletions

File tree

pythonscript/python_to_pythonjs.py

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,17 @@ def __init__(self, module=None, module_path=None):
123123
self._module = module
124124
self._module_path = module_path
125125

126-
def get_typedef(self, node):
127-
assert isinstance(node, Name)
128-
if node.id in self._instances:
129-
klass = self._instances[ node.id ]
126+
def get_typedef(self, instance=None, class_name=None):
127+
assert instance or class_name
128+
if isinstance(instance, Name) and instance.id in self._instances:
129+
class_name = self._instances[ instance.id ]
130+
131+
if class_name:
132+
assert class_name in self._classes
130133
typedef = Typedef(
131-
name = klass,
132-
methods = self._classes[ klass ],
133-
properties = self._decorator_class_props[ klass ],
134-
#compiler = self,
134+
name = class_name,
135+
methods = self._classes[ class_name ],
136+
properties = self._decorator_class_props[ class_name ],
135137
)
136138
return typedef
137139

@@ -255,7 +257,7 @@ def visit_ClassDef(self, node):
255257

256258
if self._catch_attributes:
257259
self._inline_classes[ name ] = self._catch_attributes
258-
260+
writer.write('#$---: %s' %self._function_return_types)
259261
self._catch_attributes = None
260262
self._decorator_properties = None
261263
self._instances.pop('self')
@@ -392,6 +394,23 @@ def visit_UnaryOp(self, node):
392394
return self.visit(node.op) + self.visit(node.operand)
393395

394396
def visit_Attribute(self, node):
397+
if isinstance(node.value, Name):
398+
name = self.visit( node.value )
399+
typedef = self.get_typedef( node.value )
400+
if typedef:
401+
if node.attr in typedef.properties:
402+
getter = typedef.properties[ node.attr ]['get']
403+
if getter in self._function_return_types:
404+
node.returns_type = self._function_return_types[getter]
405+
return '%s( [%s] )' %(getter, name)
406+
else:
407+
return 'get_attribute(%s, "%s")' % (name, node.attr)
408+
else:
409+
return 'get_attribute(%s, "%s")' % (name, node.attr)
410+
else:
411+
return 'get_attribute(%s, "%s")' % (self.visit(node.value), node.attr)
412+
413+
def visit_Attribute_OLD(self, node):
395414
name = self.visit(node.value)
396415
if name in self._instances: ## support '.' operator overloading
397416
klass = self._instances[ name ]
@@ -462,25 +481,50 @@ def visit_Assign(self, node):
462481
code = code % (self.visit(target.value), self.visit(target.slice.value), self.visit(node.value))
463482
writer.write(code)
464483
elif isinstance(target, Attribute):
465-
name = self.visit(target.value)
466-
if name == 'self' and isinstance(self._catch_attributes, set):
467-
self._catch_attributes.add( target.attr )
484+
#name = self.visit(target.value)
485+
#if name == 'self' and isinstance(self._catch_attributes, set):
486+
# self._catch_attributes.add( target.attr )
468487

469488
fallback = True
470-
if name in self._instances: ## support '.' operator overloading
471-
klass = self._instances[ name ]
472-
if klass in self._decorator_class_props and target.attr in self._decorator_class_props[klass]:
473-
setter = self._decorator_class_props[klass][target.attr].get( 'set', None )
489+
#if name in self._instances: ## support '.' operator overloading
490+
# klass = self._instances[ name ]
491+
# if klass in self._decorator_class_props and target.attr in self._decorator_class_props[klass]:
492+
# setter = self._decorator_class_props[klass][target.attr].get( 'set', None )
493+
# if setter:
494+
# #writer.write( '''JS('%s( [%s, %s] )')''' %(setter, name, self.visit(node.value)) ) ## can not nest have nested JS() calls
495+
# writer.write( '%s( [%s, %s] )' %(setter, name, self.visit(node.value)) )
496+
# fallback = False
497+
# else:
498+
# writer.write('#!!!! class is known: %s' %klass)
499+
#else:
500+
# writer.write('##fallback--unknown-type: %s - %s' %(target.value, name))
501+
502+
target_value = self.visit(target.value) ## target.value may have "returns_type" after being visited
503+
if isinstance(target.value, Name):
504+
if target.value.id == 'self' and isinstance(self._catch_attributes, set):
505+
self._catch_attributes.add( target.attr )
506+
507+
typedef = self.get_typedef( instance=target.value )
508+
if typedef and target.attr in typedef.properties:
509+
setter = typedef.properties[ target.attr ].get('set',None)
474510
if setter:
475-
#writer.write( '''JS('%s( [%s, %s] )')''' %(setter, name, self.visit(node.value)) ) ## can not nest have nested JS() calls
476-
writer.write( '%s( [%s, %s] )' %(setter, name, self.visit(node.value)) )
511+
writer.write( '%s( [%s, %s] )' %(setter, target_value, self.visit(node.value)) )
512+
fallback = False
513+
514+
elif hasattr(target.value, 'returns_type'):
515+
writer.write('#### HEY: %s' %target.value.returns_type)
516+
typedef = self.get_typedef( class_name=target.value.returns_type )
517+
if typedef and target.attr in typedef.properties:
518+
setter = typedef.properties[ target.attr ].get('set',None)
519+
if setter:
520+
writer.write( '%s( [%s, %s] )' %(setter, target_value, self.visit(node.value)) )
477521
fallback = False
478-
else:
479-
writer.write('#!!!! class is known: %s' %klass)
522+
480523

481524
if fallback:
525+
writer.write('#FALLBACK')
482526
code = 'set_attribute(%s, "%s", %s)' % (
483-
name,
527+
target_value,
484528
target.attr,
485529
self.visit(node.value)
486530
)
@@ -500,12 +544,17 @@ def visit_Assign(self, node):
500544
func = typedef.get_pythonjs_function_name( method )
501545
if func in self._function_return_types:
502546
self._instances[ target.id ] = self._function_return_types[ func ]
547+
else:
548+
writer.write('## %s - unknown return type for: %s'(typedef.name, func))
549+
else:
550+
writer.write('## %s - not a method: %s' %(typedef.name, method))
503551

504552
elif isinstance(node.value, Name) and node_value in self._instances: ## if this is a simple copy: "a = b" and "b" is known to be of some class
505553
self._instances[ target.id ] = self._instances[ node_value ]
506554
elif isinstance(node.value, BinOp) and hasattr(node.value, 'operator_overloading') and node.value.operator_overloading in self._function_return_types:
507555
self._instances[ target.id ] = self._function_return_types[ node.value.operator_overloading ]
508-
556+
elif hasattr(node.value, 'returns_type'):
557+
self._instances[ target.id ] = node.value.returns_type
509558
elif target.id in self._instances:
510559
self._instances.pop( target.id )
511560

0 commit comments

Comments
 (0)