def find_component(self, package, name, register_used = True): if name == "CoreObject": return root_type original_name = name name_package, name = split_name(name) candidates = [] for package_name, components in self.packages.iteritems(): if name in components: if name_package: #match package/subpackage if package_name != name_package and not package_name.endswith('.' + name_package): continue candidates.append(package_name) if not candidates: raise Exception("component %s was not found" %(original_name)) if len(candidates) > 1: if name_package in candidates: #specified in name, e.g. core.Text package_name = name_package if package in candidates: #local to current package package_name = package elif 'core' in candidates: #implicit core lookup package_name = 'core' else: raise Exception("ambiguous component %s, you have to specify one of the packages explicitly: %s" \ %(name, " ".join(map(lambda p: "%s.%s" %(p, name), candidates)))) else: package_name = candidates[0] if register_used: self.used_components.add(package_name + '.' + name) return "%s.%s" %(package_name, name)
def scan_using(self, code): for m in generator.used_re.finditer(code): name = m.group(1).strip() package, component_name = split_name(name) package = escape_package(package) self.used_components.add(name) self.used_packages.add(package)
def find_component(self, package, name, register_used=True, mangle=False, use_globals=False): if name == root_type_name: package = root_type_package #fixme: copypasted if mangle: package = mangle_package(root_type_package) if use_globals: package = "_globals." + package return package + "." + root_type_name original_name = name name_package, name = split_name(name) candidates = [] for package_name, components in self.packages.items(): if name in components: if name_package: #match package/subpackage if package_name != name_package and not package_name.endswith( '.' + name_package): continue candidates.append(package_name) if not candidates: raise Exception("component %s was not found" % (original_name)) if len(candidates) > 1: if name_package in candidates: #specified in name, e.g. core.Text package_name = name_package if package in candidates: #local to current package package_name = package elif 'core' in candidates: #implicit core lookup package_name = 'core' else: raise Exception("ambiguous component %s, you have to specify one of the packages explicitly: %s" \ %(name, " ".join(["%s.%s" %(p, name) for p in candidates]))) else: package_name = candidates[0] if register_used: self.used_components.add(package_name + '.' + name) if mangle: package_name = mangle_package(package_name) if use_globals: package_name = "_globals." + package_name return "%s.%s" % (package_name, name)
def generate_animations(self, registry, parent): r = [] for name, animation in self.animations.items(): var = "behavior_%s_on_%s" %(escape(parent), escape(name)) r.append("\tvar %s = new %s(%s)" %(var, registry.find_component(self.package, animation.component.name, mangle = True), parent)) r.append("\tvar %s$c = { %s: %s }" %(var, var, var)) r.append(self.call_create(registry, 1, var, animation, var + '$c')) r.append(self.call_setup(registry, 1, var, animation, var + '$c')) target_parent, target = split_name(name) if not target_parent: target_parent = parent else: target_parent = self.get_rvalue(registry, parent, target_parent) r.append("\t%s.setAnimation('%s', %s);\n" %(target_parent, target, var)) return "\n".join(r)
def generate_components(self): #finding explicit @used declarations in code for name, code in self.imports.iteritems(): for m in generator.used_re.finditer(code): name = m.group(1).strip() package, component_name = split_name(name) package = escape_package(package) self.used_components.add(name) self.used_packages.add(package) generated = set([root_type]) queue = ['core.Context'] code, base_class = {}, {} while queue or self.used_components: for component in self.used_components: if component not in generated: queue.append(component) self.used_components = set() if queue: name = queue.pop(0) component = self.components[name] base_type = self.find_component(component.package, component.component.name) base_class[name] = base_type code[name] = self.generate_component(component) generated.add(name) r = '' order = [] visited = set([root_type]) def visit(type): if type in visited: return visit(base_class[type]) order.append(type) visited.add(type) for type in base_class.iterkeys(): visit(type) for type in order: r += code[type] return r
def add_component(self, name, component, declaration): if name in self.components: raise Exception("duplicate component " + name) package, component_name = split_name(name) package = escape_package(package) if not declaration: name = "%s.Ui%s" %(package, component_name[0].upper() + component_name[1:]) self.used_components.add(name) self.used_packages.add(package) self.startup.append("\tcontext.start(new qml.%s(context))" %name) self.startup.append("\tcontext.run()") else: name = package + '.' + component_name if package not in self.packages: self.packages[package] = set() self.packages[package].add(component_name) gen = component_generator(self.ns, name, component, True) self.components[name] = gen
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)
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)