# HG changeset patch # User Edouard Tisserant # Date 1518908327 -3600 # Node ID 9dc0e38552b213b50294b427662646f2fc1f67ec # Parent a4382ae1ba82128369ee7bf8c69ed508e478da75 GetPouVariables optimized with XSLTModelQuery diff -r a4382ae1ba82 -r 9dc0e38552b2 PLCControler.py --- a/PLCControler.py Sat Feb 17 16:42:56 2018 +0100 +++ b/PLCControler.py Sat Feb 17 23:58:47 2018 +0100 @@ -39,6 +39,7 @@ from util.TranslationCatalogs import NoTranslate from plcopen import * from plcopen.InstancesPathCollector import InstancesPathCollector +from plcopen.POUVariablesCollector import POUVariablesCollector from graphics.GraphicCommons import * from PLCGenerator import * @@ -209,65 +210,6 @@ _translate_args([_StringValue] * 5 + [_BoolValue] + [_StringValue], args) + [self.GetType(), self.GetTree()]))) -# ------------------------------------------------------------------------------- -# Helpers object for generating pou variable instance list -# ------------------------------------------------------------------------------- - - -def class_extraction(value): - class_type = { - "configuration": ITEM_CONFIGURATION, - "resource": ITEM_RESOURCE, - "action": ITEM_ACTION, - "transition": ITEM_TRANSITION, - "program": ITEM_PROGRAM}.get(value) - if class_type is not None: - return class_type - - pou_type = POU_TYPES.get(value) - if pou_type is not None: - return pou_type - - var_type = VAR_CLASS_INFOS.get(value) - if var_type is not None: - return var_type[1] - - return None - - -class _VariablesTreeItemInfos(object): - __slots__ = ["name", "var_class", "type", "edit", "debug", "variables"] - - def __init__(self, *args): - for attr, value in zip(self.__slots__, args): - setattr(self, attr, value if value is not None else "") - - def copy(self): - return _VariablesTreeItemInfos(*[getattr(self, attr) for attr in self.__slots__]) - - -class VariablesTreeInfosFactory(object): - - def __init__(self): - self.Root = None - - def GetRoot(self): - return self.Root - - def SetRoot(self, context, *args): - self.Root = _VariablesTreeItemInfos( - *([''] + _translate_args( - [class_extraction, _StringValue] + [_BoolValue] * 2, - args) + [[]])) - - def AddVariable(self, context, *args): - if self.Root is not None: - self.Root.variables.append(_VariablesTreeItemInfos( - *(_translate_args( - [_StringValue, class_extraction, _StringValue] + - [_BoolValue] * 2, args) + [[]]))) - - class InstanceTagName(object): """Helpers object for generating instance tagname""" @@ -550,6 +492,7 @@ self.LastNewIndex = 0 self.Reset() self.InstancesPathCollector = InstancesPathCollector(self) + self.POUVariablesCollector = POUVariablesCollector(self) # Reset PLCControler internal variables def Reset(self): @@ -772,18 +715,6 @@ def GetPouVariables(self, tagname, debug=False): project = self.GetProject(debug) if project is not None: - factory = VariablesTreeInfosFactory() - - parser = etree.XMLParser() - parser.resolvers.add(LibraryResolver(self, debug)) - - pou_variable_xslt_tree = etree.XSLT( - etree.parse( - os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"), - parser), - extensions={("pou_vars_ns", name): getattr(factory, name) - for name in ["SetRoot", "AddVariable"]}) - obj = None words = tagname.split("::") if words[0] == "P": @@ -791,8 +722,7 @@ elif words[0] != "D": obj = self.GetEditedElement(tagname, debug) if obj is not None: - pou_variable_xslt_tree(obj) - return factory.GetRoot() + return self.POUVariablesCollector.Collect(obj, debug) return None diff -r a4382ae1ba82 -r 9dc0e38552b2 plcopen/POUVariablesCollector.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plcopen/POUVariablesCollector.py Sat Feb 17 23:58:47 2018 +0100 @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# This file is part of Beremiz. +# See COPYING file for copyrights details. + +from __future__ import absolute_import +from plcopen.XSLTModelQuery import XSLTModelQuery + +def class_extraction(value): + class_type = { + "configuration": ITEM_CONFIGURATION, + "resource": ITEM_RESOURCE, + "action": ITEM_ACTION, + "transition": ITEM_TRANSITION, + "program": ITEM_PROGRAM}.get(value) + if class_type is not None: + return class_type + + pou_type = POU_TYPES.get(value) + if pou_type is not None: + return pou_type + + var_type = VAR_CLASS_INFOS.get(value) + if var_type is not None: + return var_type[1] + + return None + + +class _VariablesTreeItemInfos(object): + __slots__ = ["name", "var_class", "type", "edit", "debug", "variables"] + + def __init__(self, *args): + for attr, value in zip(self.__slots__, args): + setattr(self, attr, value if value is not None else "") + + def copy(self): + return _VariablesTreeItemInfos(*[getattr(self, attr) for attr in self.__slots__]) + + +class VariablesTreeInfosFactory(object): + + def __init__(self): + self.Root = None + + def GetRoot(self): + return self.Root + + def SetRoot(self, context, *args): + self.Root = _VariablesTreeItemInfos( + *([''] + _translate_args( + [class_extraction, _StringValue] + [_BoolValue] * 2, + args) + [[]])) + + def AddVariable(self, context, *args): + if self.Root is not None: + self.Root.variables.append(_VariablesTreeItemInfos( + *(_translate_args( + [_StringValue, class_extraction, _StringValue] + + [_BoolValue] * 2, args) + [[]]))) + + + +class POUVariablesCollector(XSLTModelQuery): + """ object for collecting instances path list""" + def __init__(self, controller): + XSLTModelQuery.__init__(self, + controller, + "pou_variables.xslt", + [(name, lambda *x : getattr(self.factory, name)(*x)) + for name in ["SetRoot", "AddVariable"]]) + + def Collect(self, root, debug): + self.factory = VariablesTreeInfosFactory() + self._process_xslt(root, debug) + res = self.factory.GetRoot() + self.factory = None + return res + diff -r a4382ae1ba82 -r 9dc0e38552b2 plcopen/XSLTModelQuery.py --- a/plcopen/XSLTModelQuery.py Sat Feb 17 16:42:56 2018 +0100 +++ b/plcopen/XSLTModelQuery.py Sat Feb 17 23:58:47 2018 +0100 @@ -36,4 +36,6 @@ def _process_xslt(self, root, debug, **kwargs): self.debug = debug - return self.xslt(root,**{k:etree.XSLT.strparam(v) for k,v in kwargs.iteritems()}) + res = self.xslt(root,**{k:etree.XSLT.strparam(v) for k,v in kwargs.iteritems()}) + # print(self.xslt.error_log) + return res diff -r a4382ae1ba82 -r 9dc0e38552b2 plcopen/pou_variables.xslt --- a/plcopen/pou_variables.xslt Sat Feb 17 16:42:56 2018 +0100 +++ b/plcopen/pou_variables.xslt Sat Feb 17 23:58:47 2018 +0100 @@ -1,20 +1,14 @@ - + - - - - - - - - - + + + @@ -210,12 +204,10 @@ - - - + - - + + @@ -253,11 +245,9 @@ - - - + - + true @@ -273,12 +263,10 @@ - - - + - + false diff -r a4382ae1ba82 -r 9dc0e38552b2 plcopen/pou_variables.ysl2 --- a/plcopen/pou_variables.ysl2 Sat Feb 17 16:42:56 2018 +0100 +++ b/plcopen/pou_variables.ysl2 Sat Feb 17 23:58:47 2018 +0100 @@ -1,7 +1,7 @@ include yslt_noindent.yml2 istylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" - xmlns:ns="pou_vars_ns" + xmlns:ns="beremiz" extension-element-prefixes="ns" exclude-result-prefixes="ns" { @@ -11,16 +11,11 @@ template "text()", mode="var_edit"; template "text()", mode="var_debug"; - variable "project" { - copy "document('project')/project/*"; - } - - variable "stdlib" { - copy "document('stdlib')/stdlib/*"; - } - variable "extensions" { - copy "document('extensions')/extensions/*"; - } + variable "project", "ns:GetProject()"; + + variable "stdlib", "ns:GetStdLibs()"; + + variable "extensions", "ns:GetExtensions()"; function "add_root" { param "class"; @@ -176,14 +171,10 @@ template "*[self::ppx:type or self::ppx:baseType]/ppx:derived", mode="var_class" { param "default_class"; variable "type_name", "@name"; - variable "pou_infos" { - copy """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | - exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | - exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"""; - } + variable "pou_infos", "($project|$stdlib|$extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"; choose { - when "$pou_infos != ''" { - apply "exsl:node-set($pou_infos)", mode="var_class"; + when "$pou_infos" { + apply "$pou_infos", mode="var_class"; } otherwise { value "$default_class" @@ -227,11 +218,9 @@ template "*[self::ppx:type or self::ppx:baseType]/ppx:derived", mode="var_edit" { variable "type_name", "@name"; - variable "pou_infos" { - copy "exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"; - } + variable "pou_infos", "$project/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"; choose { - when "$pou_infos != ''" > true + when "$pou_infos" > true otherwise > false } } @@ -246,15 +235,10 @@ template "*[self::ppx:type or self::ppx:baseType]/ppx:derived", mode="var_debug" { variable "type_name", "@name"; - variable "datatype_infos" { - copy """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | - exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] | - exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] | - exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]"""; - } + variable "datatype_infos", "($project|$stdlib|$extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"; choose { when "$datatype_infos != ''" { - apply "exsl:node-set($datatype_infos)", mode="var_debug"; + apply "$datatype_infos", mode="var_debug"; } otherwise > false }