====== Values porting log ====== Here, I try to record my steps for porting the Values package from VisualWorks to Squeak. ===== Starting point ===== In your VisualWorks 8.3 image * have **{Smalltalk Transform Project} (1.4.0.3,chaider)** loaded * have **[Squeak Fileout PDFtalk] (3.0.0.2,chaider)** loaded, with empty transformations: ValuesTransform ^PackageChange new If you don't have VisualWorks and cannot create the fileOut yourself, all versions are on GitHub. The fileOut of this configuration is [[https://github.com/PortingPDFtalk/SqueakValues/releases/tag/3.0.0.2|here]]. ===== First FileIn ===== File out from VW with Squeak fileOutValues. Start squeak, open the Transcript and file in [[https://github.com/PortingPDFtalk/SqueakValues/blob/43f7e61d7dfc2ffac9063a4b3636fc2b1f3559ef/Values.Squeak.st|Values.Squeak.st]] with FileStream fileIn: 'C:\Users\Christian\Documents\image\Values.Squeak.st' it loads 1 / 4 of the file before a syntax error occurs: localSpecification "{Printvalue}> The Transcript shows: ''UndefinedObject>>DoIt (PackageManifest is Undeclared) Attempt to create ManifestValues as a subclass of nil. Possibly a class is being loaded before its superclass.'' ==== VW literal binding syntax #{} ==== VisualWorks has a special syntax for specifying a class in a namespace as literal; e.g. ''#{PDFtalk.Name}''. Fixed by adding add a transformation for the class method #localSpecification in any Value subclass. This translates ''#{Integer}'' to ''#(#Integer)'' and ''#{PDFtalk.Name}'' to ''#(#PDFtalk #Name)''. ValuesTransform ^PackageChange hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) Published as **[Squeak Fileout PDFtalk] (3.0.0.3,chaider)**. ==== Unknown superclass ==== The Transcript warning complains that the class ''ManifestValues'' cannot be created as subclass of ''PackageManifest'' which is unknown. Changed ''ChunkStream>>#writeProperties:in:parents:'' to * use ''Object'' as superclass instead of ''PackageManifest'' * renamed class to ''About'' Published as **{Smalltalk Transform Project} (1.4.0.4,chaider)**. ===== FileIn 2 ===== FileOut from VW, then fileIn [[https://github.com/PortingPDFtalk/SqueakValues/blob/89f46631c98e54aa7e4ca101826e15ceb626091a/Values.Squeak.st|Values.Squeak.st]] into a fresh Squeak image. Loads about 80% until it hits the error that ColorValue is not defined. The Transcript shows: Class>>nameRelativeTo: (Root is Undeclared) Class>>isInScope: (NameScope is Undeclared) UndefinedObject>>DoIt (ColorValue is Undeclared) UndefinedObject>>fromBytesRed:green:blue: (ColorValue is Undeclared) UndefinedObject>>fromBytesRed:green:blue: (ColorValue is Undeclared) UndefinedObject>>DoIt (ColorValue is Undeclared) UndefinedObject>>DoIt (ColorValue is Undeclared) UndefinedObject>>DoIt (ColorValue is Undeclared) UndefinedObject>>DoIt (ColorValue is Undeclared) UndefinedObject>>DoIt (ColorValue is Undeclared) ==== Missing class ==== The system class ''ColorValue'' of VW is roughly equivalent to ''Color'' in Squeak. But instead of renaming all ''ColorValue'' references to ''Color'', I define ''ColorValue'' as subclass of ''Color''. With this, the target system is not polluted with compatibility methods for ''ColorValue''. This is expressed in the transformation with #newSuperclasses. The new transform looks like: ValuesTransform ^PackageChange newSuperclasses: (Valuemap with: #{Smalltalk.ColorValue} -> #Color) hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) ==== Undeclared class references ==== The Transcript shows undeclared class references in two methods of class ''class''. Class>>nameRelativeTo: (Root is Undeclared) Class>>isInScope: (NameScope is Undeclared) To handle this, we add local changes to the transformation. Local changes refer to classes in the source system. ValuesTransform ^PackageChange newSuperclasses: (Valuemap with: #{Smalltalk.ColorValue} -> #Color) hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) localChanges: self valuesLocalTransform valuesLocalTransform ^Array with: (ClassChange classReference: #{Class} instanceChanges: (Array with: (Replace method: #nameRelativeTo: code: #_sq_nameRelativeTo:) with: (Replace method: #isInScope: code: #_sq_isInScope:))) These transformations replace the body of the existing methods of class ''Class'' with the body of the ''#code'' methods. Published as **{Smalltalk Transform Project} (1.4.0.5,chaider)** with minor changes (updated comments and corrected spelling). Published as **[Squeak Fileout PDFtalk] (3.0.0.4,chaider)** with the updated transformations. ===== FileIn 3 ===== FileOut from VW, then fileIn [[https://github.com/PortingPDFtalk/SqueakValues/blob/77bd6a94b7b0ca5f2844f0feab17414454e55c93/Values.Squeak.st|Values.Squeak.st]] into a fresh Squeak image. Loads about 85% until it hits the error that GeneralBindingReference is not defined. The Transcript shows: UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) Since GeneralBindingReference is specific to namespaces in VW, we don't need to port the class extension methods. For this we add the class to the **#unusedClasses** in our #ValuesTransform PackageChange: ValuesTransform ^PackageChange unusedClasses: #(#{Smalltalk.GeneralBindingReference}) newSuperclasses: (Valuemap with: #{Smalltalk.ColorValue} -> #Color) hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) localChanges: self valuesLocalTransform Published as **[Squeak Fileout PDFtalk] (3.0.0.5,chaider)** with the updated transformation. ===== FileIn 4 ===== FileOut from VW, then fileIn [[https://github.com/PortingPDFtalk/SqueakValues/blob/6f52f46cef184aa47b2bd48896417b6eb2d3b6d3/Values.Squeak.st|Values.Squeak.st]] into a fresh Squeak image. Loads about 97% until it hits the error that Timestamp is not defined. The Transcript shows: UndefinedObject>>DoIt (Timestamp is Undeclared) UndefinedObject>>DoIt (Timestamp is Undeclared) UndefinedObject>>DoIt (Timestamp is Undeclared) UndefinedObject>>DoIt (Timestamp is Undeclared) UndefinedObject>>DoIt (Timestamp is Undeclared) We do the same trick as in FileIn x and set DateAndTime as superclass of Timestamp. The new Transformation is: ValuesTransform ^PackageChange unusedClasses: #(#{Smalltalk.GeneralBindingReference}) newSuperclasses: (Valuemap with: #{Smalltalk.ColorValue} -> #Color with: #{Timestamp} -> #DateAndTime) hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) localChanges: self valuesLocalTransform Published as **[Squeak Fileout PDFtalk] (3.0.0.6,chaider)** with the updated transformation. ===== FileIn 5 ===== FileOut from VW, then fileIn [[https://github.com/PortingPDFtalk/SqueakValues/blob/084fcf08b7fee76e4534b57a8e4fe6336f5bc986/Values.Squeak.st|Values.Squeak.st]] into a fresh Squeak image. Loads without errors or warnings!. First milestone: Clean fileIn without errors or warnings!

Next step: fileIn the tests. ===== FileIn 6 - Tests ===== Added Squeak class method ''#fileOutValuesTesting'' analog to ''#fileOutValues'': fileOutValuesTesting self write: ('.' asFilename construct: 'ValuesTesting.Squeak.st') pundles: (Array with: (Store.Registry packageNamed: #'Values Testing')) package: #'Values-Testing' prerequisites: nil packageChanges: (Valuemap with: 'Values Testing' -> self ValuesTestingTransform) with the standard transformation for Value classes: ValuesTestingTransform ^PackageChange hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) FileOut from VW with: Squeak fileOutValuesTesting then fileIn [[https://github.com/PortingPDFtalk/SqueakValues/blob/084fcf08b7fee76e4534b57a8e4fe6336f5bc986/ValuesTesting.Squeak.st|ValuesTesting.Squeak.st]] into a Squeak image with Values loaded. Loads without errors. The Transcript shows: ValuemapTests>>testIndexedAccess (SubscriptOutOfBoundsError is Undeclared) ValuemapTests>>testIndexedAccess (SubscriptOutOfBoundsError is Undeclared) ValuemapTests>>testIndexedAccess (NonIntegerIndexError is Undeclared) ValuemapTests>>testIndexedAccess (NonIntegerIndexError is Undeclared) ValuemapTests>>testKeyedAccess (NotFoundError is Undeclared) ValuemapTests>>testRemoving (NotFoundError is Undeclared) ValuemapTests>>testRemoving (NotFoundError is Undeclared) ValuemapTests>>testRemoving (NotFoundError is Undeclared) ValuemapTests>>testRemoving (NotFoundError is Undeclared) The VW error classes are not known in Squeak. We define a rewrite of the three test methods: ValuesTestingTransform ^PackageChange hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) localChanges: (Array with: (ClassChange classReference: #{Smalltalk.ValuemapTests} instanceChanges: ((OrderedCollection new) add: (Rewrite method: #testIndexedAccess rule: #replaceSqueakErrorClasses); add: (Rewrite method: #testKeyedAccess rule: #replaceSqueakErrorClasses); add: (Rewrite method: #testRemoving rule: #replaceSqueakErrorClasses); yourself))) The rule ''#replaceSqueakErrorClasses'' in class ''ParseTreeRewriter'' (analog to ''#replaceGemstoneErrorClasses'') replaces the Error classes by string replacement: replaceSqueakErrorClasses ^(self new) replace: SubscriptOutOfBoundsError name asString with: #Error asString; replace: NonIntegerIndexError name asString with: #Error asString; replace: NotFoundError name asString with: #NotFound asString; yourself Published as **[Squeak Fileout PDFtalk] (3.0.0.7,chaider)** with the updated transformation. ===== FileIn 7 - Tests ===== FileOut [Values] and [Values Testing], then fileIn into a fresh Squeak image. Loads without errors or warnings! 2. milestone: Clean fileIn of the tests without errors or warnings!

Test results: 25 run in 0:00:00:00, 0 passes, 0 expected failures, 1 failures, 24 errors, 0 unexpected passes {{:values:2022-02-01_values.squeak.zip |This Squeak fileOut (2022-02-01)}} contains the current ''Values.Squeak.st'' and ''ValuesTesting.Squeak.st''. The next step must be done in Squeak: fix the implementation to make the tests pass and modify the transformation so that the next fileOut contains the right code. If you don't have access to VW, please send a change file.