Question
· Jul 12, 2023

Is there a good existing way to export all derived classes of a given class?

It can sometimes be useful to list or export all of the subclasses that are derived, directly or indirectly, from a given class. In Studio, the Class -> Derived Classes menu option will show such a list, but I'm not aware of a built-in API for programmatically exporting their source code.

Yesterday I wrote some code for exporting derived classes, and I'm thinking about cleaning it up and putting it on Open Exchange. But if there's a simple way to do this that someone has already figured out, I'd be happy to know about that (and help others find that solution) rather than reinventing the wheel. So:

  1. Have you ever wanted to export all of the subclasses derived from a particular class?
  2. If so, what solution did you come up with? Were you happy with it?
Discussion (4)2
Log in or sign up to continue

@Sam Duncan Here's a simple method to export subclasses. It exports all of the classes in a single XML file and prints that to the console. You can easily modify that behavior by changing the $SYSTEM.OBJ.Export() line to whatever export strategy you want.

ClassMethod ExportSubclasses(pSuper As %String) As %Status
{
  #Dim tSC As %Status = $$$OK
  #Dim tEx As %Exception.AbstractException
  #Dim tPc As %ProcedureContext
  #Dim tRs As %SQL.ClassQueryResultSet
  Try {
    #; Build a subscripted array of subclasses
    Set tStmt = ##class(%SQL.Statement).%New()
    Set tSC = tStmt.%PrepareClassQuery("%Dictionary.ClassDefinitionQuery","SubclassOf")
    If $$$ISERR(tSC) Quit
    Set tPc = tStmt.%Execute(pSuper)
    If tPc.%SQLCODE < 0 {
      Throw ##class(%Exception.SQL).CreateFromSQLCODE(tPc.%SQLCODE,tPc.%Message)
    }
    Set tRs = tPc.%NextResult()
    While tRs.%Next(.tSC) {
      Set tSubclasses(tRs.%GetData(1)_".CLS") = ""
    }
    If $$$ISOK(tSC), $DATA(tSubclasses) = 10 {
      #; Export the subclasses
      Set tSC = $SYSTEM.OBJ.Export(.tSubclasses,,"/nodisplay")
    }
  } Catch tEx {
    Set tSC = tEx.AsStatus()
  }
  Quit tSC
}
set basename="Test.Sub.Base"
set file="c:\temp\subclasses.xml"

// Get list of compiled sub-classes
do $SYSTEM.OBJ.GetDependencies(basename,.out,"/subclasses=1")
// If you didn't want the base class
kill out(basename)

// Write the classes to terminal
zwrite out

// Suffix for export
set next="" for {set next=$Order(out(next)) quit:next=""  set toExport(next_".CLS")=""}
// Fire in the hole !!
do $SYSTEM.OBJ.Export(.toExport,file,"/diffexport")

// to display different qualifier flags and values used by various OBJ methods ( /diffexport ):
do $SYSTEM.OBJ.ShowQualifiers()