Commit f52978fc authored by Thanassis Tsiodras's avatar Thanassis Tsiodras

Type annotations in parser and many utilities and mappers

parent 1ae5d468
......@@ -26,7 +26,9 @@ import os
import sys
import distutils.spawn as spawn
from typing import List
from ..commonPy.utility import panic
from ..commonPy.cleanupNodes import SetOfBadTypenames
def Version():
......@@ -37,7 +39,7 @@ def Version():
# the second param is not asnFile, it is asnFiles
def OnStartup(unused_modelingLanguage, asnFiles, outputDir, unused_badTypes):
def OnStartup(unused_modelingLanguage: str, asnFiles: List[str], outputDir: str, unused_badTypes: SetOfBadTypenames) -> None: # pylint: disable=invalid-sequence-index
# print "Use ASN1SCC to generate the structures for '%s'" % asnFile
asn1SccPath = spawn.find_executable('asn1.exe')
if not asn1SccPath:
......
......@@ -25,18 +25,20 @@ code generator A.'''
import os
import sys
import distutils.spawn as spawn
from typing import List
from ..commonPy.utility import panic
from ..commonPy.cleanupNodes import SetOfBadTypenames
def Version():
def Version() -> None:
print("Code generator: " + "$Id: c_A_mapper.py 2382 2012-06-22 08:35:33Z ttsiodras $") # pragma: no cover
# Especially for the C mapper, since we need to pass the complete ASN.1 files list to ASN1SCC,
# the second param is not asnFile, it is asnFiles
def OnStartup(unused_modelingLanguage, asnFiles, outputDir, unused_badTypes):
def OnStartup(unused_modelingLanguage: str, asnFiles: List[str], outputDir: str, unused_badTypes: SetOfBadTypenames) -> None: # pylint: disable=invalid-sequence-index
# print "Use ASN1SCC to generate the structures for '%s'" % asnFile
asn1SccPath = spawn.find_executable('asn1.exe')
if not asn1SccPath:
......
......@@ -28,12 +28,15 @@ code generator A.'''
import os
import sys
import re
import distutils.spawn as spawn
from typing import List
from ..commonPy import asnParser
from ..commonPy.utility import panic, inform
from ..commonPy.asnAST import AsnBool, AsnInt, AsnReal, AsnString, AsnEnumerated, AsnSequence, AsnSet, AsnChoice, AsnMetaMember, AsnSequenceOf, AsnSetOf
from ..commonPy.createInternalTypes import ScanChildren
from ..commonPy.cleanupNodes import SetOfBadTypenames
# The file written to
g_outputFile = None
......@@ -57,7 +60,7 @@ def CleanNameAsSimulinkWants(name):
# Especially for the C mapper, since we need to pass the complete ASN.1 files list to ASN1SCC,
# the second param is not asnFile, it is asnFiles
def OnStartup(unused_modelingLanguage, asnFiles, outputDir, unused_badTypes):
def OnStartup(unused_modelingLanguage: str, asnFiles: List[str], outputDir: str, unused_badTypes: SetOfBadTypenames) -> None: # pylint: disable=invalid-sequence-index
# print "Use ASN1SCC to generate the structures for '%s'" % asnFile
asn1SccPath = spawn.find_executable('asn1.exe')
if not asn1SccPath:
......
......@@ -23,7 +23,7 @@
#
import re
from typing import Set # NOQA pylint: disable=unused-import
from typing import Set, List # NOQA pylint: disable=unused-import
from ..commonPy.utility import panic, inform
from ..commonPy import asnParser
......@@ -31,6 +31,7 @@ from ..commonPy.asnAST import (
AsnBool, AsnInt, AsnReal, AsnString, AsnEnumerated, AsnSequence,
AsnSet, AsnChoice, AsnMetaMember, AsnSequenceOf, AsnSetOf)
from ..commonPy.createInternalTypes import ScanChildren
from ..commonPy.cleanupNodes import SetOfBadTypenames
# The file written to
g_outputFile = None
......@@ -51,7 +52,7 @@ def CleanNameAsSimulinkWants(name):
return re.sub(r'[^a-zA-Z0-9_]', '_', name)
def OnStartup(unused_modelingLanguage, unused_asnFile, outputDir, unused_badTypes):
def OnStartup(unused_modelingLanguage: str, unused_asnFiles: List[str], outputDir: str, unused_badTypes: SetOfBadTypenames) -> None: # pylint: disable=invalid-sequence-index
global g_bHasStartupRunOnce
if g_bHasStartupRunOnce:
# Don't rerun, it has already done all the work
......
......@@ -25,7 +25,7 @@ import os
import re
import random
from typing import Set, IO, Any # NOQA pylint: disable=unused-import
from typing import List, Set, IO, Any # NOQA pylint: disable=unused-import
from ..commonPy.asnAST import AsnMetaMember, AsnChoice, AsnSet, AsnSequence, AsnSequenceOf, AsnSetOf
from ..commonPy.asnParser import g_names, g_leafTypeDict, CleanNameForAST
......@@ -116,7 +116,7 @@ def FixupAstForSMP2():
g_bStartupRun = False
def OnStartup(unused_modelingLanguage, asnFiles, outputDir, unused_badTypes):
def OnStartup(unused_modelingLanguage: str, asnFiles: List[str], outputDir: str, unused_badTypes: SetOfBadTypenames) -> None: # pylint: disable=invalid-sequence-index
'''
Smp2 cannot represent constraint changes in unnamed inner types
e.g. this...
......
......@@ -28,6 +28,7 @@ from typing import IO, Any # NOQA pylint: disable=unused-import
from ..commonPy.utility import panic, inform, panicWithCallStack
from ..commonPy.aadlAST import InParam, OutParam, InOutParam
from ..commonPy.recursiveMapper import RecursiveMapper
class SynchronousToolGlueGenerator:
......@@ -35,19 +36,19 @@ class SynchronousToolGlueGenerator:
##############################################
# Parts to override for each synchronous tool
def Version(self): # pylint: disable=no-self-use
def Version(self) -> None: # pylint: disable=no-self-use
panicWithCallStack("Method undefined in a SynchronousToolGlueGenerator...") # pragma: no cover
def FromToolToASN1SCC(self): # pylint: disable=no-self-use
def FromToolToASN1SCC(self) -> RecursiveMapper: # pylint: disable=no-self-use
panicWithCallStack("Method undefined in a SynchronousToolGlueGenerator...") # pragma: no cover
def FromToolToOSS(self): # pylint: disable=no-self-use
def FromToolToOSS(self) -> RecursiveMapper: # pylint: disable=no-self-use
panicWithCallStack("Method undefined in a SynchronousToolGlueGenerator...") # pragma: no cover
def FromASN1SCCtoTool(self): # pylint: disable=no-self-use
def FromASN1SCCtoTool(self) -> RecursiveMapper: # pylint: disable=no-self-use
panicWithCallStack("Method undefined in a SynchronousToolGlueGenerator...") # pragma: no cover
def FromOSStoTool(self): # pylint: disable=no-self-use
def FromOSStoTool(self) -> RecursiveMapper: # pylint: disable=no-self-use
panicWithCallStack("Method undefined in a SynchronousToolGlueGenerator...") # pragma: no cover
def HeadersOnStartup(self, unused_modelingLanguage, unused_asnFile, unused_subProgram, unused_subProgramImplementation, unused_outputDir, unused_maybeFVname): # pylint: disable=no-self-use
......
This diff is collapsed.
import re
import sys
from typing import Any, Dict # NOQA pylint: disable=unused-import
from typing import List, Union, Optional, Any, Tuple, Dict # NOQA pylint: disable=unused-import
from lxml import etree
from .asnAST import (
AsnBool, AsnInt, AsnReal, AsnEnumerated, AsnOctetString, AsnSequenceOf,
AsnSet, AsnSetOf, AsnSequence, AsnChoice, AsnMetaMember)
AsnSet, AsnSetOf, AsnSequence, AsnChoice, AsnMetaMember, AsnNode, Lookup)
# Level of verbosity
g_verboseLevel = 0
......@@ -22,19 +22,19 @@ colors = [red, green, white, yellow]
# Lookup table for SMP2 types that map to AsnBasicNodes
class MagicSmp2SimpleTypesDict(dict):
def __getitem__(self, name):
def __getitem__(self, name: str) -> Any:
# strip 'http://www.esa.int/XXXX/YY/Smp#Bool'
# to 'http://www.esa.int/Smp#Bool'
name = re.sub(r'/\d{4}/\d{2}/', '/', name)
return super(MagicSmp2SimpleTypesDict, self).__getitem__(name)
# ---------------------------------------------------------------------------
def __contains__(self, name):
def __contains__(self, name: Any) -> bool:
name = re.sub(r'/\d{4}/\d{2}/', '/', name)
return super(MagicSmp2SimpleTypesDict, self).__contains__(name)
# ---------------------------------------------------------------------------
def has_key(self, name):
def has_key(self, name: str) -> bool:
name = re.sub(r'/\d{4}/\d{2}/', '/', name)
return name in super(MagicSmp2SimpleTypesDict, self) # type: ignore pylint: disable=unsupported-membership-test
......@@ -57,12 +57,12 @@ simpleTypesTable = MagicSmp2SimpleTypesDict({
})
def setVerbosity(level):
def setVerbosity(level: int) -> None:
global g_verboseLevel
g_verboseLevel = level
def info(level, *args):
def info(level: int, *args: Any) -> None:
"""Checks the 'level' argument against g_verboseLevel and then prints
the rest of the args, one by one, separated by a space. It also
has logic to deal with usage of one of the colors as arguments
......@@ -83,7 +83,7 @@ def info(level, *args):
return
def panic(x, coloredBanner=""):
def panic(x: str, coloredBanner: str="") -> None:
"""Notifies the user that something fatal happened and aborts. """
info(0, yellow + coloredBanner + white + '\n' + x)
sys.exit(1)
......@@ -91,13 +91,13 @@ def panic(x, coloredBanner=""):
class DashUnderscoreAgnosticDict(dict):
"""A dictionary that automatically replaces '_' to '-' in its keys. """
def __setitem__(self, key, value):
def __setitem__(self, key: Any, value: Any) -> None:
super(DashUnderscoreAgnosticDict, self).__setitem__(key.replace('_', '-'), value)
def __getitem__(self, key):
def __getitem__(self, key: Any) -> Any:
return super(DashUnderscoreAgnosticDict, self).__getitem__(key.replace('_', '-'))
def __contains__(self, key):
def __contains__(self, key: Any) -> bool:
return super(DashUnderscoreAgnosticDict, self).__contains__(key.replace('_', '-'))
......@@ -117,7 +117,7 @@ class Attributes:
base = None # type: str
sourceline = None # type: int
def __init__(self, t):
def __init__(self, t: Dict[str, Any]) -> None:
"""Argument t is an lxml Etree node."""
self._attrs = {} # type: Dict[str, Any]
for k, v in list(t.items()):
......@@ -126,17 +126,21 @@ class Attributes:
k = k[endBraceIdx + 1:]
self._attrs[k] = v
def __getattr__(self, x):
def __getattr__(self, x: str) -> Any:
return self._attrs.get(x, None)
def Clean(fieldName):
def Clean(fieldName: str) -> str:
"""When mapping field names and type names from SMP2 to ASN.1,
we need to change '_' to '-'. """
return re.sub(r'[^a-zA-Z0-9-]', '-', fieldName)
def MapSMP2Type(attrs, enumOptions, itemTypes, fields):
def MapSMP2Type(
attrs: Attributes,
enumOptions: List[Tuple[str, str]],
itemTypes: List[Any], # pylint: disable=invalid-sequence-index
fields: List[Any]) -> AsnNode: # pylint: disable=invalid-sequence-index
"""
Core mapping function. Works on the XML attributes of the lxml Etree node,
and returns a node from commonPy.asnAST.
......@@ -144,14 +148,14 @@ def MapSMP2Type(attrs, enumOptions, itemTypes, fields):
location = 'from %s, in line %s' % (attrs.base, attrs.sourceline)
info(2, "Mapping SMP2 type", location)
def getMaybe(cast, x):
def getMaybe(cast: Any, x: str) -> Optional[Any]:
try:
return cast(x)
except: # pragma: no cover
return None # pragma: no cover
dataDict = {"asnFilename": attrs.base, "lineno": attrs.sourceline}
def HandleTypesInteger():
def HandleTypesInteger() -> Union[AsnBool, AsnInt]:
lowRange = getMaybe(int, attrs.Minimum)
highRange = getMaybe(int, attrs.Maximum)
if lowRange == 0 and highRange == 1:
......@@ -163,14 +167,14 @@ def MapSMP2Type(attrs, enumOptions, itemTypes, fields):
dataDict["range"] = spanRange
return AsnInt(**dataDict)
def HandleTypesFloat():
def HandleTypesFloat() -> AsnReal:
lowRange = getMaybe(float, attrs.Minimum)
highRange = getMaybe(float, attrs.Maximum)
spanRange = [lowRange, highRange] if lowRange is not None and highRange is not None else []
dataDict["range"] = spanRange
return AsnReal(**dataDict)
def HandleTypesArray():
def HandleTypesArray() -> Union[AsnOctetString, AsnSequenceOf]:
if not itemTypes:
panic("Missing mandatory ItemType element", location) # pragma: no cover
itemTypeAttrs = Attributes(itemTypes[0])
......@@ -209,7 +213,7 @@ def MapSMP2Type(attrs, enumOptions, itemTypes, fields):
dataDict['containedType'] = containedHref
return AsnSequenceOf(**dataDict)
def HandleTypesStructure():
def HandleTypesStructure() -> Union[AsnChoice, AsnSequence]:
members = []
for field in fields:
try:
......@@ -279,12 +283,12 @@ def MapSMP2Type(attrs, enumOptions, itemTypes, fields):
panic("Failed to map... (%s)" % attrs.type, location) # pragma: no cover
def FixupOutOfOrderIdReferences(nodeTypename, asnTypesDict, idToTypeDict):
def FixupOutOfOrderIdReferences(nodeTypename: str, asnTypesDict: Lookup, idToTypeDict: Dict[str, str]) -> None:
"""Based on the uniqueness of the 'Id' elements used in
'xlink:href' remote references, we resolve the lookups of
remote types that we stored in AsnMetaMembers during MapSMP2Type()."""
node = asnTypesDict[nodeTypename]
if isinstance(node, AsnChoice) or isinstance(node, AsnSequence) or isinstance(node, AsnSet):
if isinstance(node, (AsnChoice, AsnSequence, AsnSet)):
for idx, child in enumerate(node._members):
if isinstance(child[1], AsnMetaMember):
containedType = child[1]._containedType
......@@ -295,7 +299,7 @@ def FixupOutOfOrderIdReferences(nodeTypename, asnTypesDict, idToTypeDict):
else:
panic("Could not resolve Field '%s' in type '%s' (contained: %s)..." %
(child[0], nodeTypename, containedType), node.Location()) # pragma: no cover
elif isinstance(node, AsnSequenceOf) or isinstance(node, AsnSetOf):
elif isinstance(node, (AsnSequenceOf, AsnSetOf)):
if isinstance(node._containedType, str):
containedType = node._containedType
if containedType in idToTypeDict:
......@@ -307,7 +311,8 @@ def FixupOutOfOrderIdReferences(nodeTypename, asnTypesDict, idToTypeDict):
(nodeTypename, containedType), node.Location()) # pragma: no cover
def ConvertCatalogueToASN_AST(inputSmp2Files):
def ConvertCatalogueToASN_AST(
inputSmp2Files: List[str]) -> Tuple[Lookup, Dict[str, str]]: # pylint: disable=invalid-sequence-index
"""Converts a list of input SMP2 Catalogues into an ASN.1 AST,
which it returns to the caller."""
asnTypesDict = DashUnderscoreAgnosticDict()
......@@ -398,12 +403,12 @@ def ConvertCatalogueToASN_AST(inputSmp2Files):
# Gather children node's info:
# 1. Enumeration data
enumOptions = []
enumOptions = [] # type: List[Tuple[str, str]]
if a.type == 'Types:Enumeration':
for node in t.xpath("Literal"):
enumOptions.append(
[x.replace('_', '-').lower()
for x in [node.get('Name'), node.get('Value')]])
nn = node.get('Name').replace('_', '-').lower() # type: str
vv = node.get('Value').replace('_', '-').lower() # type: str
enumOptions.append((nn, vv))
# 2. ItemType data (used in arrays)
itemTypes = t.xpath("ItemType")
......
......@@ -31,7 +31,7 @@ from . import asnAST
from .asnAST import AsnNode
def VerifyNodeRange(node):
def VerifyNodeRange(node: AsnNode) -> None:
'''This function checks that
- INTEGERs
- REALs
......@@ -64,7 +64,7 @@ on the exact location of the offending type in the ASN.1 grammar.'''
if not node._range:
panic("string (in %s) must have SIZE range set!\n" % node.Location())
elif isinstance(node, asnAST.AsnSequenceOf) or isinstance(node, asnAST.AsnSetOf):
elif isinstance(node, (asnAST.AsnSequenceOf, asnAST.AsnSetOf)):
if not node._range:
panic("SequenceOf (in %s) must have SIZE range set!\n" % node.Location())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment