dolphinsmalltalk / Dolphin

Dolphin Smalltalk Core Image
MIT License
301 stars 58 forks source link

Method category blocks always cause a merge conflict cherry-picking changes between Dolphin 7 and 8 #1138

Closed blairmcg closed 3 years ago

blairmcg commented 3 years ago

The current format for the emission of method categories into a class source file is as in the following examples.

Dolphin 7:

!Association categoriesFor: #<!comparing!public! !
!Association categoriesFor: #<=!comparing!public! !
...
!Association categoriesFor: #value!accessing!public! !
!Association categoriesFor: #value:!accessing!public! !

Dolphin 8:

!Core.Association categoriesFor: #<!comparing!public! !
!Core.Association categoriesFor: #<=!comparing!public! !
...
!Core.Association categoriesFor: #value!accessing!public! !
!Core.Association categoriesFor: #value:!accessing!public! !

The class name appears on every line, and as it is unqualified in Dolphin 7, but qualified by a namespace in Dolphin 8, every line of the block is different. If we add a new method to Association in either version, and then cherry-pick it into the other version, git will create a merge conflict for every line of the block of method categories. Merging these correctly is time consuming and error prone. As a significant percentage of changes will add or remove a method (or add/remove a method category), this conflict occurs with the majority of changes.

If the class name did not appear for every method, but only once at the top of the block, then the majority of the block would be equivalent except for any actual change to the methods/categories. Also a single class chunk would only change if the class were renamed, so very unlikely to be part of the diff being merged.

The proposal would be to change the format as follows, in this case from Dolphin 7:

!Association methodCategoriesFor!
<!comparing!public! !
<=!comparing!public! !
...
value!accessing!public! !
value:!accessing!public! !
!

This is effectively using a nested chunk sequence. Each nested sequence starts with the selector, and then a series of chunks for the category names (as before), and is terminated by an empty chunk. The whole list of category chunk sequences is terminated by another empty chunk. None of the nested content needs to be run through the Compiler (which is a plus). This can be simply implemented using most of the existing code.