--- a/ProjectDefinition.st Wed Jul 26 22:32:47 2017 +0100
+++ b/ProjectDefinition.st Mon Jul 24 21:23:16 2017 +0200
@@ -1472,18 +1472,47 @@
the class is installed as autoloaded in the image (i.e. the state in the image is taken).
If false, it is taken from an existing definition in #classNamesAndAttributes"
- |newSpec oldSpec ignored|
+ | newSpec oldSpec ignored renames |
oldSpec := self classNamesAndAttributesAsSpecArray.
ignored := self ignoredClassNames asSet.
newSpec := OrderedCollection new.
+ renames := Dictionary new.
+
+ "/ We must preserve attributes across class renames (imagine
+ "/ a platform-specific class is renamed). Generally it's not
+ "/ possible to reliably detect renames but we're doing our best
+ "/ by looking at session changeset. This works fine as long as
+ "/ one uses refactorings to rename classes - which she should
+ "/ anyeay!!
+ "/
+ "/ So here we create a mapping from old class name (currently in
+ "/ a spec) to a new class name (to appear in new spec). This map
+ "/ is used later to look up old class entry for (renamed) class
+ "/ and copy attributes over.
+ ChangeSet current do:[:chg|
+ chg isClassRenameChange ifTrue:[
+ | oldName newName |
+
+ oldName := renames keyAtValue: chg oldName ifAbsent:[ chg oldName ].
+ newName := chg className.
+ oldName = newName ifTrue:[
+ renames removeKey: oldName
+ ] ifFalse:[
+ renames at: oldName put: newName.
+ ]
+ ].
+ ].
ignoreOldEntries ifFalse:[
oldSpec do:[:oldEntry |
- |newEntry className cls |
+ | newEntry className cls |
newEntry := oldEntry copy.
- className := newEntry first.
+ "/ If (old) class has been renamed, add a new entry with new name
+ "/ and old attributes...
+ className := renames at: oldEntry first ifAbsent:[ oldEntry first ].
+ newEntry at: 1 put: className.
(ignored includes:className) ifFalse:[
cls := Smalltalk classNamed:className.
@@ -1499,7 +1528,22 @@
Force merge default class attributes with existing ones"
newEntry := self mergeDefaultClassAttributesFor: cls with: newEntry.
newSpec add:newEntry.
- ]
+ ] ifFalse:[
+ "/ Class named `className` is not present. This can be either
+ "/ because:
+ "/ * it has been deleted or
+ "/ * it's a platform specific class for some other platform
+ "/ than current one.
+ "/
+ "/ If the latter, we MUST preserve it in class list.
+ | keep |
+
+ keep := oldEntry anySatisfy:[:e | e ~~ className and:[ e ~~ #autoload and: [ e ~~ OperatingSystem platformName ]]].
+ keep ifTrue:[
+ "Force merge default class attributes with existing ones"
+ newSpec add:newEntry.
+ ].
+ ].
].
].
].
@@ -1509,7 +1553,10 @@
eachClass isJavaClass ifFalse:[
className := eachClass name.
(ignored includes:className) ifFalse:[
- oldSpecEntry := oldSpec detect:[:entry | entry first = className] ifNone:nil.
+ | oldClassName |
+
+ oldClassName := renames keyAtValue: className ifAbsent:[ className ].
+ oldSpecEntry := oldSpec detect:[:entry | entry first = oldClassName] ifNone:nil.
(ignoreOldEntries or:[oldSpecEntry isNil]) ifTrue:[
(eachClass isLoaded not or:[eachClass isPrivate not]) ifTrue:[
@@ -1561,7 +1608,7 @@
"Modified: / 08-08-2006 / 19:24:34 / fm"
"Created: / 10-10-2006 / 22:00:50 / cg"
"Modified: / 06-09-2011 / 07:48:52 / cg"
- "Modified: / 30-07-2014 / 20:40:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 27-07-2017 / 10:56:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
companyName_code