GetVariableDictionary and GetPouInterfaceReturnType optimized with new VariableInfoCollector based on XSLTModelQuery. Moved corresponding definitions out of 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()
--- 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
# -------------------------------------------------------------------------------
--- /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
+
--- 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 @@
<?xml version="1.0"?>
-<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="var_infos_ns" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
+<xsl:stylesheet xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="beremiz" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns">
<xsl:output method="xml"/>
<xsl:param name="tree"/>
<xsl:template match="text()"/>
- <xsl:variable name="project">
- <xsl:copy-of select="document('project')/project/*"/>
- </xsl:variable>
- <xsl:variable name="stdlib">
- <xsl:copy-of select="document('stdlib')/stdlib/*"/>
- </xsl:variable>
- <xsl:variable name="extensions">
- <xsl:copy-of select="document('extensions')/extensions/*"/>
- </xsl:variable>
+ <xsl:variable name="project" select="ns:GetProject()"/>
+ <xsl:variable name="stdlib" select="ns:GetStdLibs()"/>
+ <xsl:variable name="extensions" select="ns:GetExtensions()"/>
+ <xsl:variable name="all_types" select="($project | $stdlib | $extensions)/ppx:types"/>
<xsl:template match="ppx:configuration">
<xsl:apply-templates select="ppx:globalVars"/>
</xsl:template>
@@ -131,7 +126,7 @@
</xsl:variable>
<xsl:choose>
<xsl:when test="$tree='True'">
- <xsl:apply-templates mode="var_type" select="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]"/>
+ <xsl:apply-templates mode="var_type" select="$all_types/ppx:pous/ppx:pou[@name=$type_name] | $all_types/ppx:dataTypes/ppx:dataType[@name=$type_name]"/>
</xsl:when>
</xsl:choose>
<xsl:value-of select="ns:SetType($type_name)"/>
@@ -170,9 +165,7 @@
<xsl:variable name="type_name">
<xsl:value-of select="@name"/>
</xsl:variable>
- <xsl:variable name="pou_infos">
- <xsl:copy-of select="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]"/>
- </xsl:variable>
+ <xsl:variable name="pou_infos" select="$all_types/ppx:pous/ppx:pou[@name=$type_name]"/>
<xsl:choose>
<xsl:when test="$pou_infos != ''">
<xsl:text>false</xsl:text>
--- 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