Question
· Apr 30

Serialised classes, exports and development environments

We have classes in a Production environment that are causing us some issues - example attached.

When we export them from the production environment the XML contains a snippet like the following:

<UDLText name="T">
<Content><![CDATA[
//Property any As list Of %XML.String(XMLNAME = "any", XMLPROJECTION = "ANY") [ SqlFieldName = _any ];

]]></Content>
</UDLText>

When imported and compiled into an Ensemble instance this class works as expected.

When viewed/edited in a development environment we run into issues - the presentation is similar with both Studio and VS Code.

On first viewing in Studio the class source code displays like this:

If you use the extension in VS Code view the class, or export it from there, again the code displays as above (and is saved in this form to the filesystem if exported).

However, if the file is modified and saved in Studio, or modified and saved or even simply compiled (import and compile) in VS Code then the source is serialised and returned to Studio/VS Code by Ensemble as:

From part of a previous conversation with @Brett Saviano  (Request textDocument/documentSymbol failed. Error: name must not be falsy · intersystems-community/vscode-objectscript · Discussion #1530) we understand this serialisation is the correct behaviour.

However, we are left with a few of questions:

  1. Serialisation does not appear to happen when the Ensemble -> System Explorer -> Classes page exports the class - is this correct? (ie present in Ensemble with the comment as '//Property', then the exported class has '//Property' rather than '// Property')
  2. Is this likely to be the same reason that the "InterSystems" tab in VS Code exports the code without the space (they are using the same underlying mechanism)?
  3. Can anyone come with any ways in which classes such as the one attached came to be in our Production Ensemble in the first place?
  4. We tried importing and re-exporting the class using $SYSTEM.OBJ - Load(file, "cuk") to import, and Export(class, file) to export. It did not modify/serialise the class - the '//Property' was left intact.
  5. And finally, is there any way of programmatically forcing this serialisation change and exporting the changed classes - our repo was created with the non-serialised versions of these classes, and now the classes with this issue sporadically show up as "phantom changes" - not relating to the development we are actually attempting to do!  
Product version: Caché 2018.1
$ZV: Cache for Windows (x86-64) 2018.1 (Build 184U) Wed Sep 19 2018 09:09:22 EDT
Discussion (7)4
Log in or sign up to continue

Hmm, attachment isn't showing. Tried again, didn't work, so have pasted the text of the export file below:

<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2018.1 (Build 184U)" ts="2025-04-30 08:23:56">
<Class name="SCI81.s1.PatientNotification">
<Description>
Created from: http://fv-testscistore/storews/store81/scistoreservices.asmx?WSDL</Descr...
<ProcedureBlock>1</ProcedureBlock>
<Super>%SerialObject,%XML.Adaptor</Super>
<TimeChanged>63768,58466.681212</TimeChanged>
<TimeCreated>63767,58804.718434</TimeCreated>

<Parameter name="ELEMENTQUALIFIED">
<Default>1</Default>
</Parameter>

<Parameter name="NAMESPACE">
<Default>http://www.show.scot.nhs.uk/isd/SCIStore</Default>
</Parameter>

<Parameter name="XMLNAME">
<Default>PatientNotification</Default>
</Parameter>

<Parameter name="XMLSEQUENCE">
<Default>1</Default>
</Parameter>

<Property name="PatientID">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="PatientID"/>
</Property>

<Property name="MergeID">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="MergeID"/>
</Property>

<Property name="EventType">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="EventType"/>
</Property>

<Property name="Consent">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="Consent"/>
</Property>

<Property name="TransactionType">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="TransactionType"/>
</Property>

<Property name="CHI">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="CHI"/>
</Property>

<Property name="RecordType">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="RecordType"/>
</Property>

<Property name="RecordKey">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="RecordKey"/>
</Property>

<Property name="ProcessEvents">
<Type>%String</Type>
<Parameter name="MAXLEN"/>
<Parameter name="XMLNAME" value="ProcessEvents"/>
</Property>

<UDLText name="T">
<Content><![CDATA[
//Property any As list Of %XML.String(XMLNAME = "any", XMLPROJECTION = "ANY") [ SqlFieldName = _any ];

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheSerialState</Type>
<State>PatientNotificationState</State>
<StreamLocation>^SCI81.s1.PatientNotificationS</StreamLocation>
<Data name="PatientNotificationState">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>PatientID</Value>
</Value>
<Value name="2">
<Value>MergeID</Value>
</Value>
<Value name="3">
<Value>EventType</Value>
</Value>
<Value name="4">
<Value>Consent</Value>
</Value>
<Value name="5">
<Value>TransactionType</Value>
</Value>
<Value name="6">
<Value>CHI</Value>
</Value>
<Value name="7">
<Value>RecordType</Value>
</Value>
<Value name="8">
<Value>RecordKey</Value>
</Value>
<Value name="9">
<Value>ProcessEvents</Value>
</Value>
<Value name="10">
<Value>any</Value>
</Value>
</Data>
</Storage>
</Class>
</Export>

1) "Internal" tools such as Studio and System Explorer support these comments since they're valid in objectscript. However, the recommended way for classes is using the /// notation since that's what documentation and other things are generated. VS Code, I'm guessing, went for the "expected" notation rather than going for backward compatibility.

2) That would be my guess too.

3) Most likely someone modified the class to comment the property.

4) See #1

5) Assuming you don't want manually modify the class definition, you can always find the offending properties and modify(using %Dictionary classes) then compile the class definitions to change to proper notation. Then export/serialize with the changes. 

Thanks for replying:

  1. Not really what @Brett Saviano, one of the ISC maintainers of the VS Code extension, said in previous discussion on the extension's github page.
  2. Yup
  3. But how? Try and edit, using either Studio or VS Code, to produce a '//XXX' comment (no space) outside a method definition. You can't do it - the space is generated by the editors without your intervention. Hence my question - how did that space get into Ensemble in the first place?
  4. Yup
  5. In principle its not just commented out Property's, it seems to be any '//' comment with no space after the '//' when that comment is not within a method (or classmethod) definition. And finding the couple of hundred classes with such comments across a 4000 class file production is a non-trivial exercise!

Hi @Colin Brough, I'm happy to expand on my previous comments.

  1. Yes, this is correct. Exporting a class retrieves whatever is in the system global for that class and builds the text file from it. The serialization happens when the class is imported. That space must be added when the text of the class is converted to the global structure. Therefore, if you manually changed the system global to remove the space it would not show up in the export. NOTE: Please don't actually do that!
  2. Yes, this is correct. Any server functions that export code that export code in a specific format (UDL for VS Code and $SYSTEM.OBJ.ExportUDL() for example) use the same code for performing the export.
  3. The serialization I mentioned in #1 and on GitHub only happens when importing a class in UDL format (the format used for editing in Studio and VS Code), NOT XML. The space must have been removed when someone modified an XML export file directly and then re-imported it.
  4. This won't work for the reason I mentioned in #3.
  5. You could use VS Code to do this. Assuming you have a local folder containing your code open in VS Code, you can right-click on the folder and select the Import and Compile option. This will load all the files in the folder onto the server, compile them, and then refresh the local copies.