示例#1
0
	def generate_creators(self, registry, parent, closure, ident_n = 1):
		r = []
		ident = "\t" * ident_n

		if not self.prototype:
			for name in self.signals:
				r.append("%s%s.%s = _globals.core.createSignal('%s').bind(%s)" %(ident, parent, name, name, parent))

			for prop in self.properties:
				for name, default_value in prop.properties:
					args = [parent, "'%s'" %prop.type, "'%s'" %name]
					if lang.value_is_trivial(default_value):
						args.append(default_value)
					r.append("\tcore.addProperty(%s)" %(", ".join(args)))

			for name, prop in self.enums.iteritems():
				raise Exception('adding enums in runtime is unsupported, consider putting this property (%s) in prototype' %name)

		for idx, gen in enumerate(self.children):
			var = "%s$child%d" %(escape(parent), idx)
			component = registry.find_component(self.package, gen.component.name)
			r.append("%svar %s = new _globals.%s(%s)" %(ident, var, component, parent))
			r.append("%s%s.%s = %s" %(ident, closure, var, var))
			code = self.call_create(registry, ident_n, var, gen, closure)
			r.append(code)

		for target, value in self.assignments.iteritems():
			if target == "id":
				if "." in value:
					raise Exception("expected identifier, not expression")
				r.append("%s%s._setId('%s')" %(ident, parent, value))
			elif target.endswith(".id"):
				raise Exception("setting id of the remote object is prohibited")
			else:
				self.check_target_property(registry, target)

			if isinstance(value, component_generator):
				if target != "delegate":
					var = "%s$%s" %(escape(parent), escape(target))
					r.append("//creating component %s" %value.name)
					r.append("%svar %s = new _globals.%s(%s)" %(ident, var, registry.find_component(value.package, value.component.name), parent))
					r.append("%s%s.%s = %s" %(ident, closure, var, var))
					code = self.call_create(registry, ident_n, var, value, closure)
					r.append(code)
					r.append('%s%s.%s = %s' %(ident, parent, target, var))
				else:
					code = "%svar delegate = new _globals.%s(%s, true)\n" %(ident, registry.find_component(value.package, value.component.name), parent)
					code += "%svar __closure = { delegate: delegate }\n" %(ident)
					code += self.call_create(registry, ident_n + 1, 'delegate', value, '__closure') + '\n'
					code += self.call_setup(registry, ident_n + 1, 'delegate', value, '__closure') + '\n'
					r.append("%s%s.%s = (function() {\n%s\n%sreturn delegate\n}).bind(%s)" %(ident, parent, target, code, ident, parent))

		for name, target in self.aliases.iteritems():
			get, pname = generate_accessors(target)
			r.append("%score.addAliasProperty(%s, '%s', (function() { return %s; }).bind(%s), '%s')" \
				%(ident, parent, name, get, parent, pname))

		return "\n".join(r)
示例#2
0
    def add_child(self, child):
        t = type(child)
        if t is lang.Property:
            self.properties.append(child)
            for name, default_value in child.properties:
                if self.has_property(name):
                    raise Exception("duplicate property " + name)

                #print self.name, name, default_value, lang.value_is_trivial(default_value)
                if child.lazy:
                    if not isinstance(default_value, lang.Component):
                        raise Exception(
                            "lazy property must be declared with component as value"
                        )
                    if len(child.properties) != 1:
                        raise Exception(
                            "property %s is lazy, hence should be declared alone"
                            % name)
                    self.lazy_properties[
                        name] = self.create_component_generator(
                            default_value, '<lazy:%s>' % name)

                if child.const:
                    if len(child.properties) != 1:
                        raise Exception(
                            "property %s is const, hence should be declared alone"
                            % name)
                    self.const_properties[name] = default_value  #string code

                self.declared_properties[name] = child
                if default_value is not None and not child.const:
                    if not child.lazy and not lang.value_is_trivial(
                            default_value):
                        self.assign(name, default_value)
        elif t is lang.AliasProperty:
            if self.has_property(child.name):
                raise Exception("duplicate property " + child.name)
            self.aliases[child.name] = child.target
        elif t is lang.EnumProperty:
            if self.has_property(child.name):
                raise Exception("duplicate property " + child.name)
            self.enums[child.name] = child
        elif t is lang.Assignment:
            if child.target == 'id':
                raise Exception('assigning non-id for id')
            self.assign(child.target, child.value)
        elif t is lang.IdAssignment:
            self.id = child.name
            self.assign("id", child.name)
        elif t is lang.Component:
            value = self.create_component_generator(child)
            self.children.append(value)
        elif t is lang.Behavior:
            for target in child.target:
                if target in self.animations:
                    raise Exception("duplicate animation on property " +
                                    target)
                value = self.create_component_generator(
                    child.animation, "<anonymous-animation>")
                self.animations[target] = value
        elif t is lang.Method:
            for name in child.name:
                if name == 'constructor':
                    if self.ctor != '':
                        raise Exception("duplicate constructor")
                    self.ctor = "\t//custom constructor:\n\t" + child.code + "\n"
                elif name == 'prototypeConstructor':
                    if not self.prototype:
                        raise Exception(
                            'prototypeConstructor can be used only in prototypes'
                        )
                    if self.prototype_ctor != '':
                        raise Exception("duplicate constructor")
                    self.prototype_ctor = child.code
                else:
                    fullname, args, code = split_name(
                        name), child.args, child.code
                    if fullname in self.methods:
                        raise Exception("duplicate method " + name)
                    self.methods[
                        fullname] = args, code, child.event  #fixme: fix code duplication here
        elif t is lang.Signal:
            name = child.name
            if name in self.signals:
                raise Exception("duplicate signal " + name)
            self.signals.add(name)
        elif t is lang.ListElement:
            self.elements.append(child.data)
        elif t is lang.AssignmentScope:
            for assign in child.values:
                self.assign(child.target + '.' + assign.target, assign.value)
        else:
            raise Exception("unhandled element: %s" % child)
示例#3
0
    def generate_creators(self, registry, parent, closure, ident_n=1):
        r = []
        ident = "\t" * ident_n

        if not self.prototype:
            for name in self.signals:
                r.append(
                    "%s%s.%s = _globals.core.createSignal('%s').bind(%s)" %
                    (ident, parent, name, name, parent))

            for prop in self.properties:
                for name, default_value in prop.properties:
                    if prop.lazy:
                        gen = self.lazy_properties[name]
                        r.append(
                            self.generate_lazy_property(
                                registry, parent, prop.type, name, gen,
                                ident_n))
                    elif prop.const:
                        r.append(
                            self.generate_const_property(
                                registry, parent, name,
                                self.const_properties[name]))
                    else:
                        args = [parent, "'%s'" % prop.type, "'%s'" % name]
                        if lang.value_is_trivial(default_value):
                            default_value, deps = parse_deps(
                                '@error', default_value,
                                partial(self.transform_root, registry))
                            if deps:
                                raise Exception(
                                    'trivial value emits dependencies')
                            args.append(default_value)
                        r.append("\tcore.addProperty(%s)" % (", ".join(args)))

            for name, prop in self.enums.iteritems():
                raise Exception(
                    'adding enums in runtime is unsupported, consider putting this property (%s) in prototype'
                    % name)

        for idx, gen in enumerate(self.children):
            var = "%s$child%d" % (escape(parent), idx)
            component = registry.find_component(self.package,
                                                gen.component.name)
            r.append("%svar %s = new _globals.%s(%s)" %
                     (ident, var, component, parent))
            r.append("%s%s.%s = %s" % (ident, closure, var, var))
            code = self.call_create(registry, ident_n, var, gen, closure)
            r.append(code)
            r.append("%s%s.addChild(%s)" % (ident, parent, var))

        for target, value in self.assignments.iteritems():
            if target == "id":
                if "." in value:
                    raise Exception("expected identifier, not expression")
                r.append("%s%s._setId('%s')" % (ident, parent, value))
            elif target.endswith(".id"):
                raise Exception(
                    "setting id of the remote object is prohibited")
            else:
                self.check_target_property(registry, target)

            if isinstance(value, component_generator):
                if target != "delegate":
                    var = "%s$%s" % (escape(parent), escape(target))
                    r.append("//creating component %s" % value.name)
                    r.append(
                        "%svar %s = new _globals.%s(%s)" %
                        (ident, var,
                         registry.find_component(
                             value.package, value.component.name), parent))
                    r.append("%s%s.%s = %s" % (ident, closure, var, var))
                    code = self.call_create(registry, ident_n, var, value,
                                            closure)
                    r.append(code)
                    r.append('%s%s.%s = %s' % (ident, parent, target, var))
                else:
                    code = self.generate_creator_function(
                        registry, 'delegate', value, ident_n)
                    r.append("%s%s.%s = %s" % (ident, parent, target, code))

        for name, target in self.aliases.iteritems():
            get, pname = generate_accessors(
                parent, target, partial(self.transform_root, registry))
            r.append("%score.addAliasProperty(%s, '%s', function() { return %s }, '%s')" \
             %(ident, parent, name, get, pname))

        return "\n".join(r)
示例#4
0
    def generate_prototype(self, registry, ident_n=1):
        assert self.prototype == True

        r = []
        ident = "\t" * ident_n

        base_type = self.get_base_type(registry)

        r.append(
            "%svar %s = %s.prototype = Object.create(%s)\n" %
            (ident, self.proto_name, self.local_name, self.base_proto_name))
        if self.prototype_ctor:
            r.append("\t%s\n" % (self.prototype_ctor))
        r.append("%s%s.constructor = %s\n" %
                 (ident, self.proto_name, self.local_name))

        r.append("%s%s.componentName = '%s'" %
                 (ident, self.proto_name, self.name))

        for name in self.signals:
            r.append("%s%s.%s = _globals.core.createSignal('%s')" %
                     (ident, self.proto_name, name, name))

        for prop in self.properties:
            for name, default_value in prop.properties:
                if prop.lazy:
                    gen = self.lazy_properties[name]
                    r.append(
                        self.generate_lazy_property(registry, self.proto_name,
                                                    prop.type, name, gen,
                                                    ident_n))
                elif prop.const:
                    r.append(
                        self.generate_const_property(
                            registry, self.proto_name, name,
                            self.const_properties[name]))
                else:
                    args = [
                        "%s" % self.proto_name,
                        "'%s'" % prop.type,
                        "'%s'" % name
                    ]
                    if lang.value_is_trivial(default_value):
                        default_value, deps = parse_deps(
                            '@error', default_value,
                            partial(self.transform_root, registry))
                        if deps:
                            raise Exception('trivial value emits dependencies')
                        args.append(default_value)
                    r.append("%score.addProperty(%s)" %
                             (ident, ", ".join(args)))

        for name, prop in self.enums.iteritems():
            values = prop.values

            for i in xrange(0, len(values)):
                r.append("/** @const @type {number} */")
                r.append("%s%s.%s = %d" %
                         (ident, self.proto_name, values[i], i))
                r.append("/** @const @type {number} */")
                r.append("%s%s.%s = %d" %
                         (ident, self.local_name, values[i], i))

            args = [self.proto_name, "'enum'", "'%s'" % name]
            if prop.default is not None:
                args.append("%s.%s" % (self.local_name, prop.default))
            r.append("%score.addProperty(%s)" % (ident, ", ".join(args)))

        def next_codevar(lines, code, index):
            var = "$code$%d" % index
            code = '%svar %s = %s' % (ident, var, code)
            lines.append(code)
            return var

        def put_in_prototype(handler):
            path, name = handler
            return not path and self.prototype

        code_index = 0

        for code, methods in self.transform_handlers(registry, self.methods):
            if len(methods) > 1:
                code = next_codevar(r, code, code_index)
                code_index += 1

            for path, name in methods:
                if path:
                    raise Exception(
                        'no <id> qualifiers (%s) allowed in prototypes %s (%s)'
                        % (path, name, self.name))
                r.append("%s%s.%s = %s" % (ident, self.proto_name, name, code))

        for code, handlers in self.transform_handlers(registry,
                                                      self.changed_handlers):
            handlers = filter(put_in_prototype, handlers)
            if not handlers:
                continue

            if len(handlers) > 1:
                code = next_codevar(r, code, code_index)
                code_index += 1

            for (path, name) in handlers:
                assert not path
                r.append("%s_globals.core._protoOnChanged(%s, '%s', %s)" %
                         (ident, self.proto_name, name, code))

        for code, handlers in self.transform_handlers(registry,
                                                      self.signal_handlers):
            handlers = filter(
                lambda h: put_in_prototype(h) and h[1] != 'completed',
                handlers)
            if not handlers:
                continue

            if len(handlers) > 1:
                code = next_codevar(r, code, code_index)
                code_index += 1

            for path, name in handlers:
                r.append("%s_globals.core._protoOn(%s, '%s', %s)" %
                         (ident, self.proto_name, name, code))

        for code, handlers in self.transform_handlers(registry,
                                                      self.key_handlers):
            handlers = filter(put_in_prototype, handlers)
            if not handlers:
                continue

            if len(handlers) > 1:
                code = next_codevar(r, code, code_index)
                code_index += 1

            for (path, name) in handlers:
                r.append("%s_globals.core._protoOnKey(%s, '%s', %s)" %
                         (ident, self.proto_name, name, code))

        generate = False

        code = self.generate_creators(registry, '$this', '$c',
                                      ident_n + 1).strip()
        if code:
            generate = True
        b = '\t%s%s.$c.call(this, $c.$b = { })' % (ident, self.base_proto_name)
        code = '%s%s.$c = function($c) {\n\t\tvar $this = this;\n%s\n%s\n%s}' \
         %(ident, self.proto_name, b, code, ident)

        setup_code = self.generate_setup_code(registry, '$this', '$c',
                                              ident_n + 2).strip()
        b = '%s%s.$s.call(this, $c.$b); delete $c.$b' % (ident,
                                                         self.base_proto_name)
        if setup_code:
            generate = True
        setup_code = '%s%s.$s = function($c) {\n\t\tvar $this = this;\n%s\n%s\n}' \
         %(ident, self.proto_name, b, setup_code)

        if generate:
            r.append('')
            r.append(code)
            r.append(setup_code)
            r.append('')

        return "\n".join(r)
示例#5
0
	def add_child(self, child):
		t = type(child)
		if t is lang.Property:
			self.properties.append(child)
			for name, default_value in child.properties:
				if self.has_property(name):
					raise Exception("duplicate property " + name)
				#print name, default_value, lang.value_is_trivial(default_value)
				self.declared_properties[name] = child
				if default_value is not None:
					if not lang.value_is_trivial(default_value):
						self.assign(name, default_value)
		elif t is lang.AliasProperty:
			if self.has_property(child.name):
				raise Exception("duplicate property " + child.name)
			self.aliases[child.name] = child.target
		elif t is lang.EnumProperty:
			if self.has_property(child.name):
				raise Exception("duplicate property " + child.name)
			self.enums[child.name] = child
		elif t is lang.Assignment:
			if child.target == 'id':
				raise Exception('assigning non-id for id')
			self.assign(child.target, child.value)
		elif t is lang.IdAssignment:
			self.id = child.name
			self.assign("id", child.name)
		elif t is lang.Component:
			self.children.append(component_generator(self.ns, self.package + ".<anonymous>", child))
		elif t is lang.Behavior:
			for target in child.target:
				if target in self.animations:
					raise Exception("duplicate animation on property " + target);
				self.animations[target] = component_generator(self.ns, self.package + ".<anonymous-animation>", child.animation)
		elif t is lang.Method:
			fullname, args, code = split_name(child.name), child.args, child.code
			path, name = fullname
			if child.event and len(name) > 2 and name != "onChanged" and name.startswith("on") and name[2].isupper(): #onXyzzy
				name = name[2].lower() + name[3:]
				fullname = path, name
				if name.endswith("Pressed"):
					name = name[0].upper() + name[1:-7]
					fullname = path, name
					if fullname in self.key_handlers:
						raise Exception("duplicate key handler " + child.name)
					self.key_handlers[fullname] = code
				elif name.endswith("Changed"):
					name = name[:-7]
					fullname = path, name
					if fullname in self.changed_handlers:
						raise Exception("duplicate signal handler " + child.name)
					self.changed_handlers[fullname] = code
				else:
					if fullname in self.signal_handlers:
						raise Exception("duplicate signal handler " + child.name)
					self.signal_handlers[fullname] = args, code
			else:
				if fullname in self.methods:
					raise Exception("duplicate method " + name)
				self.methods[fullname] = args, code
		elif t is lang.Constructor:
			self.ctor = "\t//custom constructor:\n\t" + child.code + "\n"
		elif t is lang.Signal:
			name = child.name
			if name in self.signals:
				raise Exception("duplicate signal " + name)
			self.signals.add(name)
		elif t is lang.ListElement:
			self.elements.append(child.data)
		elif t is lang.AssignmentScope:
			for assign in child.values:
				self.assign(child.target + '.' + assign.target, assign.value)
		else:
			raise Exception("unhandled element: %s" %child)
示例#6
0
	def generate_prototype(self, registry, ident_n = 1):
		assert self.prototype == True

		#HACK HACK: make immutable
		registry.id_set = set(['context'])
		self.collect_id(registry.id_set)

		r = []
		ident = "\t" * ident_n

		base_type = self.get_base_type(registry)

		r.append("%svar %s = %s.prototype = Object.create(%s)\n" %(ident, self.proto_name, self.local_name, self.base_proto_name))
		r.append("%s%s.constructor = %s\n" %(ident, self.proto_name, self.local_name))

		r.append("%s%s.componentName = '%s'" %(ident, self.proto_name, self.name))

		for name in self.signals:
			r.append("%s%s.%s = _globals.core.createSignal('%s')" %(ident, self.proto_name, name, name))

		for _name, argscode in self.methods.iteritems():
			path, name = _name
			if path:
				raise Exception('no <id> qualifiers (%s) allowed in prototypes %s (%s)' %(path, name, self.name))
			args, code = argscode
			code = process(code, self, registry)
			r.append("%s%s.%s = function(%s) %s" %(ident, self.proto_name, name, ",".join(args), code))

		for prop in self.properties:
			for name, default_value in prop.properties:
				args = ["%s" %self.proto_name, "'%s'" %prop.type, "'%s'" %name]
				if lang.value_is_trivial(default_value):
					args.append(default_value)
				r.append("%score.addProperty(%s)" %(ident, ", ".join(args)))

		for name, prop in self.enums.iteritems():
			values = prop.values

			for i in xrange(0, len(values)):
				r.append("/** @const @type {number} */")
				r.append("%s%s.%s = %d" %(ident, self.proto_name, values[i], i))
				r.append("/** @const @type {number} */")
				r.append("%s%s.%s = %d" %(ident, self.local_name, values[i], i))

			args = [self.proto_name, "'enum'", "'%s'" %name]
			if prop.default is not None:
				args.append("%s.%s" %(self.local_name, prop.default))
			r.append("%score.addProperty(%s)" %(ident, ", ".join(args)))

		for _name, code in self.changed_handlers.iteritems():
			path, name = _name
			if path or not self.prototype: #sync with condition below
				continue

			assert not path
			code = process(code, self, registry)
			r.append("%s_globals.core._protoOnChanged(%s, '%s', (function(value) %s ))" %(ident, self.proto_name, name, code))

		for _name, argscode in self.signal_handlers.iteritems():
			path, name = _name
			if path or not self.prototype or name == 'completed': #sync with condition below
				continue
			args, code = argscode
			code = process(code, self, registry)
			r.append("%s_globals.core._protoOn(%s, '%s', (function(%s) %s ))" %(ident, self.proto_name, name, ", ".join(args), code))

		for _name, code in self.key_handlers.iteritems():
			path, name = _name
			if path or not self.prototype: #sync with condition below
				continue
			code = process(code, self, registry)
			r.append("%s_globals.core._protoOnKey(%s, '%s', (function(key, event) %s ))" %(ident, self.proto_name, name, code))


		generate = False

		code = self.generate_creators(registry, 'this', '__closure', ident_n + 1).strip()
		if code:
			generate = True
		b = '\t%s%s.__create.call(this, __closure.__base = { })' %(ident, self.base_proto_name)
		code = '%s%s.__create = function(__closure) {\n%s\n%s\n%s}' \
			%(ident, self.proto_name, b, code, ident)

		setup_code = self.generate_setup_code(registry, 'this', '__closure', ident_n + 2).strip()
		b = '%s%s.__setup.call(this, __closure.__base); delete __closure.__base' %(ident, self.base_proto_name)
		if setup_code:
			generate = True
		setup_code = '%s%s.__setup = function(__closure) {\n%s\n%s\n}' \
			%(ident, self.proto_name, b, setup_code)

		if generate:
			r.append('')
			r.append(code)
			r.append(setup_code)
			r.append('')

		return "\n".join(r)