Show pageOld revisionsBacklinksFold/unfold allBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== 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: <code Smalltalk>ValuesTransform ^PackageChange new</code> 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 <code Smalltalk>Squeak fileOutValues</code>. Start squeak, open the Transcript and file in [[https://github.com/PortingPDFtalk/SqueakValues/blob/43f7e61d7dfc2ffac9063a4b3636fc2b1f3559ef/Values.Squeak.st|Values.Squeak.st]] with <code Smalltalk>FileStream fileIn: 'C:\Users\Christian\Documents\image\Values.Squeak.st'</code> it loads 1 / 4 of the file before a syntax error occurs: <code Smalltalk>localSpecification <constant: #name class: #"Invalid literal character ->"{Printvalue}> <constant: #value class: #{Printvalue}></code> 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)''. <code Smalltalk>ValuesTransform ^PackageChange hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath))))</code> 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<Package>'' 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: <code Smalltalk>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)</code> ==== 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: <code Smalltalk>ValuesTransform ^PackageChange newSuperclasses: (Valuemap with: #{Smalltalk.ColorValue} -> #Color) hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath))))</code> ==== Undeclared class references ==== The Transcript shows undeclared class references in two methods of class ''class''. <code>Class>>nameRelativeTo: (Root is Undeclared) Class>>isInScope: (NameScope is Undeclared)</code> To handle this, we add local changes to the transformation. Local changes refer to classes in the source system. <code Smalltalk>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:)))</code> 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: <code Smalltalk> UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) UndefinedObject>>DoIt (GeneralBindingReference is Undeclared) </code> 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: <code Smalltalk>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 </code> 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: <code Smalltalk> 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) </code> We do the same trick as in FileIn x and set DateAndTime as superclass of Timestamp. The new Transformation is: <code Smalltalk> 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 </code> 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!. <HTML> First milestone: <span style="background-color:yellow;font-size:150%;border:2px solid lightgray;">Clean fileIn without errors or warnings!</span><br><br> </HTML> Next step: fileIn the tests. ===== FileIn 6 - Tests ===== Added Squeak class method ''#fileOutValuesTesting'' analog to ''#fileOutValues'': <code Smalltalk>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) </code> with the standard transformation for Value classes: <code Smalltalk> ValuesTestingTransform ^PackageChange hierarchyChanges: (Array with: (ClassChange classReference: #{Smalltalk.Value} classChanges: (Array with: (Rewrite method: #localSpecification rule: #replaceLiteralBindingWithPath)))) </code> FileOut from VW with: <code Smalltalk>Squeak fileOutValuesTesting</code> 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: <code Smalltalk> 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) </code> The VW error classes are not known in Squeak. We define a rewrite of the three test methods: <code Smalltalk> 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))) </code> The rule ''#replaceSqueakErrorClasses'' in class ''ParseTreeRewriter'' (analog to ''#replaceGemstoneErrorClasses'') replaces the Error classes by string replacement: <code Smalltalk> 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 </code> 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! <HTML> 2. milestone: <span style="background-color:yellow;font-size:150%;border:2px solid lightgray;">Clean fileIn of the tests without errors or warnings!</span><br><br> </HTML> 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. valuesportinglog.txt Last modified: 2022/02/27 13:34by christian