7373]
7474
7575
76+ class SolutionLoaderError (Exception ):
77+ """Solution loader-related exception base class."""
78+
79+
80+ class UnsupportedSourceFileError (SolutionLoaderError ):
81+ """
82+ Unsupported project file.
83+
84+ blark does not support loading of these compilable items:
85+ 1. GlobalTextList
86+ 2. Any other non-structured text source code files
87+ """
88+
89+ type : Optional [str ] = None
90+
91+ def __init__ (self , msg : str , type : Optional [str ] = None ):
92+ self .type = type
93+ super ().__init__ (msg )
94+
95+
7696@functools .lru_cache (maxsize = 2048 )
7797def strip_xml_namespace (tag : str ) -> str :
7898 """Strip off {{namespace}} from: {{namespace}}tag."""
@@ -439,19 +459,29 @@ def from_xml(
439459 xml : lxml .etree .Element ,
440460 filename : Optional [pathlib .Path ] = None ,
441461 parent : Optional [TwincatSourceCodeItem ] = None ,
442- ) -> Optional [ Union [TcDUT , TcTTO , TcPOU , TcIO , TcGVL ] ]:
462+ ) -> Union [TcDUT , TcTTO , TcPOU , TcIO , TcGVL ]:
443463 tcplc_object = get_tcplc_from_xml (xml )
444464 if tcplc_object is None :
445- return None
465+ plc_attribs = {}
466+ else :
467+ plc_attribs = tcplc_object .attrib
468+
446469 source_cls , item = get_code_object_from_xml (xml )
447470 if source_cls is None or item is None :
448- raise RuntimeError (
449- f"Unsupported xml type for TcSource: { xml } "
471+ try :
472+ child_type = xml .getchildren ()[0 ].tag
473+ except Exception :
474+ child_type = "unknown"
475+ raise UnsupportedSourceFileError (
476+ f"Unsupported xml type for TcSource in "
477+ f"{ filename_from_xml (xml )} : { xml .tag } /{ child_type } "
478+ f"(parent={ parent } )" ,
479+ type = child_type ,
450480 )
451481
452482 metadata = dict (item .attrib )
453- metadata ["version" ] = tcplc_object . attrib .get ("Version" , "" )
454- metadata ["product_version" ] = tcplc_object . attrib .get ("ProductVersion" , "" )
483+ metadata ["version" ] = plc_attribs .get ("Version" , "" )
484+ metadata ["product_version" ] = plc_attribs .get ("ProductVersion" , "" )
455485
456486 decl = TcDeclImpl .from_xml (
457487 item ,
@@ -481,15 +511,19 @@ def from_contents(
481511 contents : bytes ,
482512 filename : Optional [pathlib .Path ] = None ,
483513 parent : Optional [TcSource ] = None ,
484- ) -> Optional [Union [TcDUT , TcPOU , TcIO , TcTTO , TcGVL ]]:
485- return cls .from_xml (parse_xml_contents (contents ), filename = filename , parent = parent )
514+ ) -> Union [TcDUT , TcPOU , TcIO , TcTTO , TcGVL ]:
515+ return cls .from_xml (
516+ parse_xml_contents (contents ),
517+ filename = filename ,
518+ parent = parent ,
519+ )
486520
487521 @classmethod
488522 def from_filename (
489523 cls : type [Self ],
490524 filename : AnyPath ,
491525 parent : Optional [TcSource ] = None ,
492- ) -> Optional [ Union [TcDUT , TcPOU , TcIO , TcTTO , TcGVL ] ]:
526+ ) -> Union [TcDUT , TcPOU , TcIO , TcTTO , TcGVL ]:
493527 with open (filename , "rb" ) as fp :
494528 raw_contents = fp .read ()
495529 return cls .from_contents (raw_contents , filename = pathlib .Path (filename ), parent = parent )
@@ -995,6 +1029,9 @@ class TcUnknownXml:
9951029 xml : lxml .etree .Element
9961030 parent : TcSource
9971031
1032+ def to_blark (self ) -> list [BlarkSourceItem ]:
1033+ return []
1034+
9981035
9991036@dataclasses .dataclass
10001037class TwincatSourceCodeItem :
@@ -1015,12 +1052,12 @@ class TwincatSourceCodeItem:
10151052 subtype : Optional [str ]
10161053 #: Link always set?
10171054 link_always : bool
1055+ #: Raw file contents.
1056+ raw_contents : bytes
1057+ #: Contents loaded into a type-specific class.
1058+ contents : Union [TcDUT , TcPOU , TcIO , TcGVL , TcTTO ]
10181059 #: The globally unique identifier for the source code item.
10191060 guid : Optional [str ] = None
1020- #: Raw file contents.
1021- raw_contents : bytes = b''
1022- #: Raw contents loaded into a type-specific class.
1023- contents : Optional [Union [TcDUT , TcPOU , TcIO , TcGVL , TcTTO ]] = None
10241061 #: The parent project, if applicable.
10251062 parent : Optional [TwincatPlcProject ] = None
10261063
@@ -1064,11 +1101,19 @@ def from_compile_xml(
10641101 else :
10651102 with open (local_path , "rb" ) as fp :
10661103 raw_contents = fp .read ()
1067- contents = TcSource .from_contents (
1068- raw_contents ,
1069- filename = local_path ,
1070- parent = None ,
1071- )
1104+ try :
1105+ contents = TcSource .from_contents (
1106+ raw_contents ,
1107+ filename = local_path ,
1108+ parent = None ,
1109+ )
1110+ except UnsupportedSourceFileError :
1111+ logger .debug (
1112+ "Unsupported source code file not loaded: %s" ,
1113+ local_path ,
1114+ exc_info = True ,
1115+ )
1116+ return None
10721117
10731118 namespaces = {"msbuild" : xml .xpath ("namespace-uri()" )}
10741119 subtype = get_child_text (
@@ -1647,10 +1692,6 @@ def twincat_file_loader(
16471692 return project_loader (filename )
16481693
16491694 source = TcSource .from_filename (filename )
1650- if source is None :
1651- logger .warning ("No source found in file %s (is this in error?)" , filename )
1652- return []
1653-
16541695 return source .to_blark ()
16551696
16561697
0 commit comments