# HG changeset patch # User Edouard Tisserant # Date 1519122250 -3600 # Node ID bbd1e1744c9123f34dd67fca9805cbcc2df44d3d # Parent 752ec68da94dd5ba8b4959b29bd62f6c174dca27 GetVariableDictionary and GetPouInterfaceReturnType optimized with new VariableInfoCollector based on XSLTModelQuery. Moved corresponding definitions out of PLCControler.py. diff -r 752ec68da94d -r bbd1e1744c91 PLCControler.py --- a/PLCControler.py Mon Feb 19 15:46:50 2018 +0100 +++ b/PLCControler.py Tue Feb 20 11:24:10 2018 +0100 @@ -43,6 +43,7 @@ from plcopen.InstancesPathCollector import InstancesPathCollector from plcopen.POUVariablesCollector import POUVariablesCollector from plcopen.InstanceTagnameCollector import InstanceTagnameCollector +from plcopen.VariableInfoCollector import VariableInfoCollector from graphics.GraphicCommons import * from PLCGenerator import * @@ -74,60 +75,6 @@ # ------------------------------------------------------------------------------- -# Helpers object for generating pou var list -# ------------------------------------------------------------------------------- - - -class _VariableInfos(object): - __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", - "Edit", "Documentation", "Type", "Tree", "Number"] - - 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 _VariableInfos(*[getattr(self, attr) for attr in self.__slots__]) - - -class VariablesInfosFactory(object): - - def __init__(self, variables): - self.Variables = variables - self.TreeStack = [] - self.Type = None - self.Dimensions = None - - def SetType(self, context, *args): - self.Type = args[0][0] - - def GetType(self): - if len(self.Dimensions) > 0: - return ("array", self.Type, self.Dimensions) - return self.Type - - def GetTree(self): - return (self.TreeStack.pop(-1), self.Dimensions) - - def AddDimension(self, context, *args): - self.Dimensions.append(tuple( - _translate_args([_StringValue] * 2, args))) - - def AddTree(self, context, *args): - self.TreeStack.append([]) - self.Dimensions = [] - - def AddVarToTree(self, context, *args): - var = (args[0][0], self.Type, self.GetTree()) - self.TreeStack[-1].append(var) - - def AddVariable(self, context, *args): - self.Variables.append(_VariableInfos(*( - _translate_args([_StringValue] * 5 + [_BoolValue] + [_StringValue], args) + - [self.GetType(), self.GetTree()]))) - - -# ------------------------------------------------------------------------------- # Helpers object for generating pou block instances list # ------------------------------------------------------------------------------- @@ -385,6 +332,7 @@ self.InstancesPathCollector = InstancesPathCollector(self) self.POUVariablesCollector = POUVariablesCollector(self) self.InstanceTagnameCollector = InstanceTagnameCollector(self) + self.VariableInfoCollector = VariableInfoCollector(self) # Reset PLCControler internal variables def Reset(self): @@ -1162,21 +1110,8 @@ def GetVariableDictionary(self, object_with_vars, tree=False, debug=False): variables = [] - factory = VariablesInfosFactory(variables) - - parser = etree.XMLParser() - parser.resolvers.add(LibraryResolver(self, debug)) - - variables_infos_xslt_tree = etree.XSLT( - etree.parse( - os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), - parser), - extensions={("var_infos_ns", name): getattr(factory, name) - for name in ["SetType", "AddDimension", "AddTree", - "AddVarToTree", "AddVariable"]}) - variables_infos_xslt_tree( - object_with_vars, tree=etree.XSLT.strparam(str(tree))) - + factory = self.VariableInfoCollector.Collect(object_with_vars, + debug, variables, tree) return variables # Add a global var to configuration to configuration @@ -1329,20 +1264,8 @@ # Return the return type if there is one return_type = pou.interface.getreturnType() if return_type is not None: - factory = VariablesInfosFactory([]) - - parser = etree.XMLParser() - parser.resolvers.add(LibraryResolver(self)) - - return_type_infos_xslt_tree = etree.XSLT( - etree.parse( - os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), - parser), - extensions={("var_infos_ns", name): getattr(factory, name) - for name in ["SetType", "AddDimension", - "AddTree", "AddVarToTree"]}) - return_type_infos_xslt_tree( - return_type, tree=etree.XSLT.strparam(str(tree))) + factory = self.VariableInfoCollector.Collect(return_type, + debug, [], tree) if tree: return [factory.GetType(), factory.GetTree()] return factory.GetType() diff -r 752ec68da94d -r bbd1e1744c91 controls/VariablePanel.py --- a/controls/VariablePanel.py Mon Feb 19 15:46:50 2018 +0100 +++ b/controls/VariablePanel.py Tue Feb 20 11:24:10 2018 +0100 @@ -39,7 +39,7 @@ from controls.LocationCellEditor import LocationCellEditor from util.BitmapLibrary import GetBitmap from util.TranslationCatalogs import NoTranslate -from PLCControler import _VariableInfos +from plcopen.VariableInfoCollector import _VariableInfos # ------------------------------------------------------------------------------- diff -r 752ec68da94d -r bbd1e1744c91 plcopen/VariableInfoCollector.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plcopen/VariableInfoCollector.py Tue Feb 20 11:24:10 2018 +0100 @@ -0,0 +1,87 @@ +#!/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, _StringValue, _BoolValue, _translate_args + +# ------------------------------------------------------------------------------- +# Helpers object for generating pou var list +# ------------------------------------------------------------------------------- + +class _VariableInfos(object): + __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", + "Edit", "Documentation", "Type", "Tree", "Number"] + + 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 _VariableInfos(*[getattr(self, attr) for attr in self.__slots__]) + + +class VariablesInfosFactory(object): + """ Helpers object for generating pou var list """ + + def __init__(self, variables): + self.Variables = variables + self.TreeStack = [] + self.Type = None + self.Dimensions = None + + def SetType(self, context, *args): + self.Type = args[0][0] + + def GetType(self): + if len(self.Dimensions) > 0: + return ("array", self.Type, self.Dimensions) + return self.Type + + def GetTree(self): + return (self.TreeStack.pop(-1), self.Dimensions) + + def AddDimension(self, context, *args): + self.Dimensions.append(tuple( + _translate_args([_StringValue] * 2, args))) + + def AddTree(self, context, *args): + self.TreeStack.append([]) + self.Dimensions = [] + + def AddVarToTree(self, context, *args): + var = (args[0][0], self.Type, self.GetTree()) + self.TreeStack[-1].append(var) + + def AddVariable(self, context, *args): + self.Variables.append(_VariableInfos(*( + _translate_args([_StringValue] * 5 + [_BoolValue] + [_StringValue], args) + + [self.GetType(), self.GetTree()]))) + + +class VariableInfoCollector(XSLTModelQuery): + def __init__(self, controller): + XSLTModelQuery.__init__(self, + controller, + "variables_infos.xslt", + [(name, self.FactoryCaller(name)) + for name in [ + "SetType", + "AddDimension", + "AddTree", + "AddVarToTree", + "AddVariable"]]) + + def FactoryCaller(self, funcname): + def CallFactory(*args): + return getattr(self.factory, funcname)(*args) + return CallFactory + + def Collect(self, root, debug, variables, tree): + self.factory = VariablesInfosFactory(variables) + self._process_xslt(root, debug, tree=str(tree)) + res = self.factory + self.factory = None + return res + diff -r 752ec68da94d -r bbd1e1744c91 plcopen/variables_infos.xslt --- a/plcopen/variables_infos.xslt Mon Feb 19 15:46:50 2018 +0100 +++ b/plcopen/variables_infos.xslt Tue Feb 20 11:24:10 2018 +0100 @@ -1,17 +1,12 @@ - + - - - - - - - - - + + + + @@ -131,7 +126,7 @@ - + @@ -170,9 +165,7 @@ - - - + false diff -r 752ec68da94d -r bbd1e1744c91 plcopen/variables_infos.ysl2 --- a/plcopen/variables_infos.ysl2 Mon Feb 19 15:46:50 2018 +0100 +++ b/plcopen/variables_infos.ysl2 Tue Feb 20 11:24:10 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="var_infos_ns" + xmlns:ns="beremiz" extension-element-prefixes="ns" exclude-result-prefixes="ns" { @@ -9,17 +9,14 @@ template "text()"; - 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()"; + + variable "all_types", "($project | $stdlib | $extensions)/ppx:types"; + template "ppx:configuration" { apply "ppx:globalVars"; } @@ -129,12 +126,8 @@ variable "type_name" > «@name» choose { when "$tree='True'" { - apply """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:pous/ppx:pou[@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:pous/ppx:pou[@name=$type_name] | - exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]""", mode="var_type"; + apply """$all_types/ppx:pous/ppx:pou[@name=$type_name] | \ + $all_types/ppx:dataTypes/ppx:dataType[@name=$type_name]""", mode="var_type"; } } value "ns:SetType($type_name)"; @@ -166,11 +159,7 @@ template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/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] | - 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", "$all_types/ppx:pous/ppx:pou[@name=$type_name]"; choose { when "$pou_infos != ''" > false otherwise > true