'From Squeak3.7alpha of 11 September 2003 [latest update: #5816] on 11 March 2004 at 1:19:02 am'! "Change Set: q20renameVariable-yo Date: 18 January 2004, revised 3/17/04 Author: Yoshiki Ohshima Derived from Squeakland updates 0198renameVariable-yo.cs and 0203langChgFix-sw.cs. Integrated with 3.7a/5816 by Scott Wallace 10 March 04. Make the rename variable feature work. As long as the variable is not used in textually coded scripts, the cases like it is referenced in the other player's script, multiple occurrence in more than one script, etc, are solved. This update also fixes the long-standing bug that the menu-title of the slot-info-button could show an internal slot symbol (e.g. useGradientFill) rather than an external variable name (e.g. gradientFill). Some refinements and fixes added by Scott Wallace 7 March 04."! !Morph methodsFor: 'e-toy support' stamp: 'yo 1/9/2004 16:10'! allMorphsAndBookPagesInto: aSet "Return a set of all submorphs. Don't forget the hidden ones like BookMorph pages that are not showing. Consider only objects that are in memory (see allNonSubmorphMorphs)." submorphs do: [:m | m allMorphsAndBookPagesInto: aSet]. self allNonSubmorphMorphs do: [:m | (aSet includes: m) ifFalse: ["Stop infinite recursion" m allMorphsAndBookPagesInto: aSet]]. aSet add: self. self player ifNotNil: [self player allScriptEditors do: [:e | e allMorphsAndBookPagesInto: aSet]]. ^ aSet! ! !Morph methodsFor: 'translation' stamp: 'sw 3/7/2004 13:03'! isPlayer: aPlayer ofReferencingTile: tile "Answer whether the given player is the object referred to by the given tile, or a sibling of that object. This theoretically is only sent to PhraseTileMorphs, so this version is theoretically never reached" ^ false! ! !Morph methodsFor: 'translation' stamp: 'yo 1/18/2004 10:31'! traverseRowTranslateSlotOld: oldSlotName of: aPlayer to: newSlotName "Traverse my submorphs, translating submorphs appropriately given the slot rename" submorphs do: [:tile | (tile isKindOf: AssignmentTileMorph) ifTrue: [tile assignmentRoot = oldSlotName ifTrue: [(self isPlayer: aPlayer ofReferencingTile: tile) ifTrue: [tile setRoot: newSlotName]]]. (tile isMemberOf: TileMorph) ifTrue: [(tile operatorOrExpression = (Utilities getterSelectorFor: oldSlotName)) ifTrue: [(self isPlayer: aPlayer ofReferencingTile: tile) ifTrue: [tile setOperator: (Utilities getterSelectorFor: newSlotName)]]]. tile traverseRowTranslateSlotOld: oldSlotName of: aPlayer to: newSlotName]! ! !Morph methodsFor: 'translation' stamp: 'yo 1/18/2004 10:32'! traverseRowTranslateSlotOld: oldSlotName to: newSlotName "Traverse my submorphs, translating submorphs appropriately given the slot rename" submorphs do: [:tile | (tile isKindOf: AssignmentTileMorph) ifTrue: [tile assignmentRoot = oldSlotName ifTrue: [tile setRoot: newSlotName]]. (tile isMemberOf: TileMorph) ifTrue: [(tile operatorOrExpression = (Utilities getterSelectorFor: oldSlotName)) ifTrue: [tile setOperator: (Utilities getterSelectorFor: newSlotName)]]. tile traverseRowTranslateSlotOld: oldSlotName to: newSlotName]! ! !AssignmentTileMorph methodsFor: 'initialization' stamp: 'yo 1/1/2004 19:50'! setRoot: aString "Establish the assignment root, and update the label on the tile" assignmentRoot _ aString. self updateLiteralLabel! ! !AssignmentTileMorph methodsFor: 'player viewer' stamp: 'yo 1/1/2004 19:51'! assignmentRoot "Answer the assignment root" ^ assignmentRoot! ! !Player methodsFor: 'scripts-kernel' stamp: 'yo 1/2/2004 06:40'! noteRenameOf: oldSlotName to: newSlotName inPlayer: aPlayer "Note that aPlayer has renamed a slot formerly known as oldSlotName to be newSlotName" self allScriptEditors do: [:anEditor | (anEditor showingMethodPane not and: [anEditor hasScriptReferencing: oldSlotName ofPlayer: aPlayer]) ifTrue: [anEditor replaceReferencesToSlot: oldSlotName inPlayer: aPlayer with: newSlotName]]! ! !Player methodsFor: 'scripts-kernel' stamp: 'sw 3/10/2004 17:52'! slotInfoButtonHitFor: aGetterSymbol inViewer: aViewer "The user made a gesture asking for slot menu for the given getter symbol in a viewer; put up the menu." | aMenu slotSym aType typeVocab interface selector | slotSym _ Utilities inherentSelectorForGetter: aGetterSymbol. aType _ self typeForSlotWithGetter: aGetterSymbol asSymbol. aMenu _ MenuMorph new defaultTarget: self. interface := aViewer currentVocabulary methodInterfaceAt: aGetterSymbol ifAbsent: [nil]. selector := interface isNil ifTrue: [slotSym asString] ifFalse: [interface wording]. aMenu addTitle: (selector, ' (', (aType asString translated), ')'). (typeVocab _ Vocabulary vocabularyForType: aType) addWatcherItemsToMenu: aMenu forGetter: aGetterSymbol. (self slotInfo includesKey: slotSym) ifTrue: [aMenu add: 'change data type' translated selector: #chooseSlotTypeFor: argument: aGetterSymbol. typeVocab addUserSlotItemsTo: aMenu slotSymbol: slotSym. aMenu add: ('remove "{1}"' translated format: {slotSym}) selector: #removeSlotNamed: argument: slotSym. aMenu add: ('rename "{1}"' translated format: {slotSym}) selector: #renameSlot: argument: slotSym. aMenu addLine]. typeVocab addExtraItemsToMenu: aMenu forSlotSymbol: slotSym. "e.g. Player type adds hand-me-tiles" aMenu add: 'show categories....' translated target: aViewer selector: #showCategoriesFor: argument: aGetterSymbol. self addIdiosyncraticMenuItemsTo: aMenu forSlotSymol: slotSym. aMenu items isEmpty ifTrue: [aMenu add: 'ok' translated action: #yourself]. aMenu popUpForHand: aViewer primaryHand in: aViewer world! ! !Player methodsFor: 'slots-user' stamp: 'sw 3/7/2004 15:56'! allPossibleWatchersFromWorld "Answer a list of all UpdatingStringMorphs in the Active world and its hidden book pages, etc., which have any of my instances as targets" | a | a _ IdentitySet new: 400. ActiveWorld allMorphsAndBookPagesInto: a. ^ a select: [:e | (e isKindOf: UpdatingStringMorph) and: [e target class == self class]]! ! !Player methodsFor: 'slots-user' stamp: 'sw 3/8/2004 22:14'! renameSlot: oldSlotName newSlotName: newSlotName "Give an existing instance variable a new name" self class renameSilentlyInstVar: oldSlotName to: newSlotName. self renameSlotInWatchersOld: oldSlotName new: newSlotName. self updateAllViewers. self presenter allExtantPlayers do: [:aPlayer | (aPlayer hasScriptReferencing: oldSlotName ofPlayer: self) ifTrue: [aPlayer noteRenameOf: oldSlotName to: newSlotName inPlayer: self]]. self presenter hasAnyTextuallyCodedScripts ifTrue: [self inform: 'Caution!! References in texutally coded scripts won''t be renamed.']. ^ true! ! !Player methodsFor: 'translation' stamp: 'yo 1/18/2004 10:59'! labelFromWatcher: w "Answer the morph holding the label of the given watcher" ^ w owner owner submorphs third submorphs second! ! !Player methodsFor: 'translation' stamp: 'sw 3/7/2004 14:35'! renameSlotInWatchersOld: oldName new: newName "A variable has been renamed; get all relevant extant watchers updated. All this assumed to be happening in the ActiveWorld" | wasStepping oldGetter | oldGetter _ Utilities getterSelectorFor: oldName. self allPossibleWatchersFromWorld do: [:aWatcher | (aWatcher getSelector = oldGetter) ifTrue: [(wasStepping _ aWatcher isStepping) ifTrue: [aWatcher stopStepping]. aWatcher getSelector: (Utilities getterSelectorFor: newName). aWatcher putSelector ifNotNil: [aWatcher putSelector: (Utilities setterSelectorFor: newName)]. aWatcher hasStructureOfComplexWatcher ifTrue: [aWatcher owner owner traverseRowTranslateSlotOld: oldName to: newName. (aWatcher target labelFromWatcher: aWatcher) contents: newName, ' = ']. wasStepping ifTrue: [aWatcher startStepping]]]! ! !Presenter methodsFor: 'playerList' stamp: 'sw 3/8/2004 22:09'! hasAnyTextuallyCodedScripts "Answer whether any uniclasses in the receiver have any textually coded scripts" self uniclassesAndCounts do: [:classAndCount | classAndCount first scripts do: [:aScript | aScript isTextuallyCoded ifTrue: [^ true]]]. ^ false " ActiveWorld presenter hasAnyTextuallyCodedScripts "! ! !ScriptEditorMorph methodsFor: 'e-toy support' stamp: 'yo 1/18/2004 10:34'! replaceReferencesToSlot: oldSlotName inPlayer: aPlayer with: newSlotName "An instance variable has been renamed in a player; replace all references to the old instance variable of that player such that they become references to the new slot" self tileRows do: [:row | row do: [:c | c traverseRowTranslateSlotOld: oldSlotName of: aPlayer to: newSlotName]]. self install. self fixLayout! ! !ScriptEditorMorph methodsFor: 'e-toy support' stamp: 'yo 1/13/2004 17:56'! setNaturalLanguageTo: aLangauge "With the natural language in the surrounding project having changed, get wording correct" self fixLayout! ! !ScriptEditorMorph methodsFor: 'menu' stamp: 'yo 1/11/2004 03:15'! fixLayout "Tell all morphs that their layout has changed, using a sledge-hammer" self allMorphs do: [:e | e layoutChanged]! ! !ScriptEditorMorph methodsFor: 'menus' stamp: 'yo 1/11/2004 03:15'! addCustomMenuItems: aCustomMenu hand: aHandMorph "Add custom menu items to a menu" super addCustomMenuItems: aCustomMenu hand: aHandMorph. aCustomMenu addUpdating: #autoFitString target: self action: #autoFitOnOff. aCustomMenu addLine. aCustomMenu add: 'fix layout' target: self action: #fixLayout! ! !ScriptEditorMorph methodsFor: 'other' stamp: 'yo 1/14/2004 10:50'! hasScriptReferencing: aSlotName ofPlayer: aPlayer "Answer whether the receiver has any tiles in it which reference the given slot of the given player. By doing a text search on the decompiled method, this is able to work both with text and with tiles. The approach is still not perfect, because we can't really know until run-time whom the getters and setters are sent to. But practically speaking, this is all presumably a positive." | stringToSearch | "(aPlayer isKindOf: playerScripted class) ifFalse: [^ false]." stringToSearch _ (playerScripted class compiledMethodAt: scriptName) decompileString. {Utilities getterSelectorFor: aSlotName. Utilities setterSelectorFor: aSlotName} do: [:searchee | (stringToSearch findString: searchee startingAt: 1) = 0 ifFalse: [^ true]]. ^ false! ! !TileLikeMorph methodsFor: 'initialization' stamp: 'ka 5/9/2002 21:40'! setNaturalLanguageTo: aLangauge "With the natural language in the surrounding project having changed, get wording correct" self updateWordingToMatchVocabulary! ! !TileLikeMorph methodsFor: 'user interface' stamp: 'sw 3/10/2004 19:55'! updateWordingToMatchVocabulary "If appropriate, change the wording on the receiver to match up with a changed vocabulary."! ! !PhraseTileMorph methodsFor: 'miscellaneous' stamp: 'sw 3/7/2004 13:04'! isPlayer: aPlayer ofReferencingTile: tile "Answer whether a given player is the object referred to by the given tile, or a sibling of that object." ^ aPlayer class == self actualObject class! ! !UpdatingStringMorph methodsFor: 'target access' stamp: 'sw 3/7/2004 15:49'! hasStructureOfComplexWatcher "Answer whether the receiver has precisely the structure of a so-called complex watcher, as used in the etoy system." | top | top _ (self owner ifNil: [^ false]) owner. ^ ((((top isMemberOf: AlignmentMorph) and: [top submorphs size = 4]) and: [top submorphs first isMemberOf: TileMorph]) and: [top submorphs third isMemberOf: AlignmentMorph])! !