def visit_ClassDef(self, node):
		node._parents = set()
		out = []
		extends = False ## Dart has no support for multiple inheritance!
		props = set(['$wrapped'])
		bases = set()
		base_classes = set()

		self._classes[ node.name ] = node
		self._class_props[ node.name ] = props
		for decor in node.decorator_list:  ## class decorators
			if isinstance(decor, ast.Call):
				props.update( [self.visit(a) for a in decor.args] )
			elif isinstance(decor, ast.Attribute) and isinstance(decor.value, ast.Name) and decor.value.id == 'dart':
				if decor.attr == 'extends':
					extends = True
					props.add('$wrapped')
					for name_node in collect_names( node ):
						if name_node.id == 'self':
							name_node.id = 'this'
			else:
				raise SyntaxError


		for base in node.bases:
			n = self.visit(base)
			if n == 'object':
				continue
			node._parents.add( n )

			bases.add( n )
			if n in self._class_props:
				props.update( self._class_props[n] )
				base_classes.add( self._classes[n] )
			else:  ## special case - subclassing a builtin like `list`
				continue

			for p in self._classes[ n ]._parents:
				bases.add( p )
				props.update( self._class_props[p] )
				base_classes.add( self._classes[p] )

		if bases:
			if extends:
				assert len(bases) == 1
				out.append('class %s extends %s {'%(node.name, ','.join(bases)))
			else:
				#if bases[0] == 'object':
				#	out.append('class %s {' %node.name)
				#else:
				out.append('class %s implements %s {'%(node.name, ', '.join(bases)))


		else:
			out.append('class %s {' %node.name)
		self.push()

		for p in props:
			out.append(self.indent()+ 'var %s;'%p)

		method_names = set()
		for b in node.body:

			if isinstance(b, ast.With):
				out.append( self.visit(b) )
			elif isinstance(b, ast.FunctionDef) and len(b.decorator_list):  ##getter/setters
				for name_node in collect_names( b ):
					if name_node.id == 'self':
						name_node.id = 'this'

				b.args.args = b.args.args[1:]
				out.append( self.visit(b) )

			elif extends:
				if isinstance(b, ast.FunctionDef):
					b.args.args = b.args.args[1:]
					if b.name == node.name:
						args = [self.visit(a) for a in b.args.args]
						args = ','.join(args)
						out.append(
							self.indent()+'%s(%s) : super() { this.__init__(%s); }'%(node.name, args, args)
						)
						b.name = '__init__'
					elif b.name == '__getitem__':
						b.name = ''
						b._prefix = 'operator []'
					elif b.name == '__setitem__':
						b.name = ''
						b._prefix = 'void operator []='
					elif b.name == '__add__':
						b.name = ''
						b._prefix = 'operator +'
					elif b.name == '__iadd__':
						b.name = ''
						b._prefix = 'void operator +='
					elif b.name == '__sub__':
						b.name = ''
						b._prefix = 'operator -'
					elif b.name == '__mul__':
						b.name = ''
						b._prefix = 'operator *'
					elif b.name == '__div__':
						b.name = ''
						b._prefix = 'operator /'

					elif b.name == '__or__':
						b.name = ''
						b._prefix = 'operator |'
					elif b.name == '__xor__':
						b.name = ''
						b._prefix = 'operator ^'



				line = self.visit(b)
				out.append( line )

			elif isinstance(b, ast.FunctionDef) and b.name == node.name:
				args, kwargs = self.get_args_kwargs_from_funcdef(b, skip_self=True)
				kwargs_init = ['%s:%s' %(x.split(':')[0], x.split(':')[0]) for x in kwargs]

				#args = [self.visit(a) for a in b.args.args][1:]
				#args = ','.join(args)
				b._prefix = 'static void'
				b.name = '__init__'
				out.append( self.visit(b) )
				if args:
					args = ','.join(args)
					if kwargs:
						out.append(
							self.indent()+'%s(%s, {%s}) {%s.__init__(this,%s,%s);}'%(node.name, args, ','.join(kwargs), node.name, args, ','.join(kwargs_init))
						)

					else:
						out.append(
							self.indent()+'%s(%s) {%s.__init__(this,%s);}'%(node.name, args, node.name, args)
						)
				elif kwargs:
					out.append(
						self.indent()+'%s( {%s} ) {%s.__init__(this,%s);}'%(node.name, ','.join(kwargs), node.name, ','.join(kwargs_init))
					)

				else:
					out.append(
						self.indent()+'%s() {%s.__init__(this);}'%(node.name, node.name)
					)

			elif isinstance(b, ast.FunctionDef):
				method_names.add( b.name )
				TransformSuperCalls( b, bases )

				operator = False
				if b.name == '__getitem__':
					operator = 'operator []'
				elif b.name == '__setitem__':
					operator = 'operator []='
				elif b.name == '__add__':
					operator = 'operator +'
				elif b.name == '__sub__':
					operator = 'operator -'
				elif b.name == '__mul__':
					operator = 'operator *'
				elif b.name == '__div__':
					operator = 'operator /'
				elif b.name == '__and__':
					operator = 'operator &'
				elif b.name == '__or__':
					operator = 'operator |'
				elif b.name == '__xor__':
					operator = 'operator ^'
				elif b.name == '__lshift__':
					operator = 'operator <<'
				elif b.name == '__rshift__':
					operator = 'operator >>'

				args = [self.visit(a) for a in b.args.args][1:]
				args = ','.join(args)
				if operator and args:
					out.append(self.indent()+ '%s(%s) { return %s.__%s(this,%s); }'%(operator, args, node.name, b.name, args) )

				elif operator:
					out.append(self.indent()+ '%s() { return %s.__%s(this); }'%(operator, node.name, b.name) )

				elif args:
					out.append(self.indent()+ '%s(%s) { return %s.__%s(this,%s); }'%(b.name, args, node.name, b.name, args) )
				else:
					out.append(self.indent()+ '%s() { return %s.__%s(this); }'%(b.name, node.name, b.name) )

				b._prefix = 'static'
				name = b.name
				b.name = '__%s'%name
				out.append( self.visit(b) )
				b.name = name

			else:
				line = self.visit(b)
				if line.startswith('var '):
					out.append( self.indent()+line )
				else:
					out.append( line )

		if not extends and base_classes:
			for bnode in base_classes:
				for b in bnode.body:
					if isinstance(b, ast.FunctionDef):
						if b.name == '__init__': continue
						if b.name in method_names: continue

						args = [self.visit(a) for a in b.args.args][1:]
						args = ','.join(args)
						if args:
							out.append(self.indent()+ '%s(%s) { return %s.__%s(this,%s); }'%(b.name, args, bnode.name, b.name, args) )
						else:
							out.append(self.indent()+ '%s() { return %s.__%s(this); }'%(b.name, bnode.name, b.name) )


		self.pull()
		out.append('}')
		return '\n'.join(out)
dataset/ETHPy150Open PythonJS/PythonJS/pythonjs/pythonjs_to_dart.py/DartGenerator.visit_ClassDef/original