'From Squeak3.9alpha of ''2 November 2004'' [latest update: #6601] on 30 March 2005 at 10:05:09 pm'! "Change Set: 6603CleaningUtilities Date: 30 March 2005 Author: stephane ducasse Move some utilities close to the class they use, i.e. Scanner"! !Object methodsFor: 'viewer' stamp: 'sd 3/30/2005 22:04'! uniqueInstanceVariableNameLike: aString excluding: takenNames "Answer a nice instance-variable name to be added to the receiver which resembles aString, making sure it does not coincide with any element in takenNames" | okBase uniqueName usedNames | usedNames _ self class allInstVarNamesEverywhere. usedNames removeAllFoundIn: self class instVarNames. usedNames addAll: takenNames. okBase _ Scanner wellFormedInstanceVariableNameFrom: aString. uniqueName _ Utilities keyLike: okBase satisfying: [:aKey | (usedNames includes: aKey) not]. ^ uniqueName! ! !Morph methodsFor: 'card in a stack' stamp: 'sd 3/30/2005 22:04'! abstractAModel "Find data-containing fields in me. Make a new class, whose instance variables are named for my fields, and whose values are the values I am showing. Use a CardPlayer for now. Force the user to name the fields. Make slots for text, Number Watchers, SketchMorphs, and ImageMorphs." | instVarNames unnamed ans player twoListsOfMorphs holdsSepData docks oldPlayer iVarName | (oldPlayer := self player) ifNotNil: [oldPlayer belongsToUniClass ifTrue: ["Player" oldPlayer class instVarNames notEmpty ifTrue: [self inform: 'I already have a regular Player, so I can''t have a CardPlayer'. ^true]]]. twoListsOfMorphs := StackMorph discoverSlots: self. holdsSepData := twoListsOfMorphs first. instVarNames := ''. holdsSepData do: [:ea | iVarName := Scanner wellFormedInstanceVariableNameFrom: ea knownName. iVarName = ea knownName ifFalse: [ea name: iVarName]. instVarNames := instVarNames , iVarName , ' ']. unnamed := twoListsOfMorphs second. "have default names" instVarNames isEmpty ifTrue: [self inform: 'No named fields were found. Please get a halo on each field and give it a name. Labels or non-data fields should be named "shared xxx".'. ^false]. unnamed notEmpty ifTrue: [ans := PopUpMenu confirm: 'Data fields are ' , instVarNames printString , ('\Some fields are not named. Are they labels or non-data fields?' , '\Please get a halo on each data field and give it a name.') withCRs trueChoice: 'All other fields are non-data fields' falseChoice: 'Stop. Let me give a name to some more fields'. ans ifFalse: [^false]]. unnamed withIndexDo: [:mm :ind | mm setName: 'shared label ' , ind printString]. "Make a Player with instVarNames. Make me be the costume" player := CardPlayer instanceOfUniqueClassWithInstVarString: instVarNames andClassInstVarString: ''. self player: player. player costume: self. "Fill in the instance values. Make docks first." docks := OrderedCollection new. holdsSepData do: [:morph | morph setProperty: #shared toValue: true. "in case it is deeply embedded" morph setProperty: #holdsSeparateDataForEachInstance toValue: true. player class compileInstVarAccessorsFor: morph knownName. morph isSyntaxMorph ifTrue: [morph setTarget: player]. "hookup the UpdatingString!!" docks addAll: morph variableDocks]. player class newVariableDocks: docks. docks do: [:dd | dd storeMorphDataInInstance: player]. "oldPlayer class mdict do: [:assoc | move to player]. move methods to new class?" "oldPlayer become: player." ^true "success"! ! !Morph methodsFor: 'e-toy support' stamp: 'sd 3/30/2005 22:04'! defaultVariableName "If the receiver is of the sort that wants a variable maintained on its behalf in the 'card' data, then return a variable name to be used for that datum. What is returned here is only a point of departure in the forthcoming negotiation" ^ Scanner wellFormedInstanceVariableNameFrom: (self valueOfProperty: #variableName ifAbsent: [self externalName])! ! !Scanner class methodsFor: 'testing' stamp: 'sd 3/30/2005 22:00'! inviolateInstanceVariableNames "Answer a list of instance variable names not to be used. (Place holder for real list)" ^ #('thisContext' 'self')! ! !Scanner class methodsFor: 'testing' stamp: 'sd 3/30/2005 22:00'! isLegalInstVarName: aString "Answer whether aString is a legal instance variable name." ^ ((self isLiteralSymbol: aString) and: [(aString includes: $:) not]) and: [(self inviolateInstanceVariableNames includes: aString) not]! ! !Scanner class methodsFor: 'testing' stamp: 'sd 3/30/2005 22:01'! wellFormedInstanceVariableNameFrom: aString "Answer a legal instance variable name, derived from aString" | cleansedString | cleansedString _ aString select: [:ch | ch isDigit or: [ch isLetter]]. (cleansedString size == 0 or: [cleansedString first isDigit]) ifTrue: [cleansedString _ 'a', cleansedString] ifFalse: [cleansedString _ cleansedString withFirstCharacterDownshifted]. [self isLegalInstVarName: cleansedString] whileFalse: [cleansedString _ cleansedString, 'x']. ^ cleansedString "Scanner wellFormedInstanceVariableNameFrom: '234 xx\ Uml /ler42342380-4'"! ! !Utilities class methodsFor: 'deprecated' stamp: 'sd 3/30/2005 21:53'! browseVersionsForClass: aClass selector: aSelector self deprecated: 'Use VersionsBrowser browseVersionsForClass: aClass selector: aSelector instead'. VersionsBrowser browseVersionsForClass: aClass selector: aSelector! ! !Utilities class methodsFor: 'deprecated' stamp: 'sd 3/30/2005 22:02'! inviolateInstanceVariableNames "Answer a list of instance variable names not to be used. (Place holder for real list)" self deprecated: 'Use Scanner inviolateInstanceVariableNames instead'. ^ Scanner inviolateInstanceVariableNames! ! !Utilities class methodsFor: 'deprecated' stamp: 'sd 3/30/2005 22:02'! isLegalInstVarName: aString "Answer whether aString is a legal instance variable name." self deprecated: 'Use Scanner isLegalInstVarName: aString instead'. ^ Scanner isLegalInstVarName: aString! ! !Utilities class methodsFor: 'deprecated' stamp: 'sd 3/30/2005 22:03'! wellFormedInstanceVariableNameFrom: aString "Answer a legal instance variable name, derived from aString" self deprecated: 'Use Scanner wellFormedInstanceVariableNameFrom: aString instead'. ^ Scanner wellFormedInstanceVariableNameFrom: aString! ! !VersionsBrowser class methodsFor: 'instance creation' stamp: 'sd 3/30/2005 21:53'! browseVersionsForClass: aClass selector: aSelector self browseVersionsOf: (aClass compiledMethodAt: aSelector) class: aClass meta: aClass isMeta category: (aClass organization categoryOfElement: aSelector) selector: aSelector! ! !VersionsBrowser class reorganize! ('instance creation' browseVersionsForClass:selector: browseVersionsOf:class:meta:category:selector: browseVersionsOf:class:meta:category:selector:lostMethodPointer: timeStampFor:class:reverseOrdinal: versionCountForSelector:class:) ('window color' windowColorSpecification) ! !Utilities class reorganize! ('class initialization' initialize registerInFlapsRegistry startUp unload) ('common requests' appendToCommonRequests: closeAllDebuggers commonRequestStrings: editCommonRequestStrings eval: evaluate:in:to: initializeCommonRequestStrings offerCommonRequests offerCommonRequestsInMorphic) ('debugging' doesNotUnderstand: inspectCollection:notifying:) ('durable menus' windowFromMenu:target:title: windowFromMenu:target:title:colorPattern: windowMenuWithLabels:colorPattern:targets:selections:title: windowMenuWithLabels:colorPattern:targets:selections:wordingSelectors:title:) ('fetching updates' applyUpdatesFromDisk applyUpdatesFromDiskToUpdateNumber:stopIfGap: assureAbsenceOfUnstableUpdateStream assureAvailabilityOfUnstableUpdateStream broadcastUpdatesFrom:to:except: chooseUpdateList extractThisVersion: fileInFromUpdatesFolder: getUpdateDirectoryOrNil lastUpdateNum: newUpdatesOn:special:throughNumber: objectStrmFromUpdates: parseListContents: position:atVersion: readNextUpdateFromServer readNextUpdatesFromDisk: readServer:special:updatesThrough:saveLocally:updateImage: readServerUpdatesSaveLocally:updateImage: readServerUpdatesThrough:saveLocally:updateImage: retrieveUrls:ontoQueue:withWaitSema: saveUpdate:onFile: serverUrls setUpdateServer: summariesForUpdates:through: updateComment updateFromServer updateFromServerThroughUpdateNumber: updateUrlLists writeList:toStream: zapUpdateDownloader) ('deprecated' browseVersionsForClass:selector: fileOutChangeSetsNamed: fileOutChanges globalFlapTabOrDummy: grabScreenAndSaveOnDisk hierarchyOfClassesSurrounding: hierarchyOfImplementorsOf:forClass: inspectGlobals inviolateInstanceVariableNames isLegalInstVarName: isObject:memberOfOneOf: makeNihongoImage methodHierarchyBrowserForClass:selector: spawnHierarchyForClass:selector: stripMethods:messageCode: vmStatisticsReportString vmStatisticsShortString wellFormedInstanceVariableNameFrom:) ('graphical support' showFormsAcrossTopOfScreen: showFormsDictAcrossTopOfScreen:) ('identification' authorInitials authorInitialsPerSe authorName authorName: authorNamePerSe browseUncommentedMethodsWithInitials: changeStamp changeStampPerSe copyrightNotice dateStamp dateTimeSuffix fixStamp: methodsWithInitials: monthDayTime24StringFrom: monthDayTimeStringFrom: setAuthorInitials setAuthorInitials: setAuthorName) ('investigations' reportSenderCountsFor:) ('miscellaneous' addSampleWindowsTo: awaitMouseUpIn:repeating:ifSucceed: awaitMouseUpIn:whileMouseDownDo:whileMouseDownInsideDo:ifSucceed: cleanseOtherworldlySteppers convertCRtoLF: createPageTestWorkspace decimalPlacesForFloatPrecision: decommissionTheAllCategory doesMethod:forClass:bearInitials: emergencyCollapse fixUpProblemsWithAllCategory floatPrecisionForDecimalPlaces: garbageCollectAndReport getterSelectorFor: inherentSelectorForGetter: instanceComparisonsBetween:and: keyLike:satisfying: keyLike:withTrailing:satisfying: lookUpDefinition methodDiffFor:class:selector:prettyDiffs: nextClockwiseSideAfter: openScratchWorkspaceLabeled:contents: oppositeCornerFrom: oppositeModeTo: oppositeSideTo: reconstructTextWindowsFromFileNamed: setClassAndSelectorFrom:in: setterSelectorFor: simpleSetterFor: steplistToolsWorkspace storeTextWindowContentsToFileNamed: timeStampForMethod:) ('recent method submissions' assureMostRecentSubmissionExists browseRecentSubmissions dumpAnyOldStyleRecentSubmissions event: mostRecentlySubmittedMessage noteMethodSubmission:forClass: numberOfRecentSubmissionsToStore numberOfRecentSubmissionsToStore: openRecentSubmissionsBrowser purgeFromRecentSubmissions: purgeRecentSubmissionsOfMissingMethods recentMethodSubmissions recentSubmissionsWindow revertLastMethodSubmission) ('scraps' addToTrash: emptyScrapsBook maybeEmptyTrash scrapsBook trashTitle) ('summer97 additions' chooseFileWithSuffix: chooseFileWithSuffixFromList:withCaption: classCategoriesStartingWith: classFromPattern:withCaption: graphicsFileSuffixes) ('support windows' commandKeyMappings openCommandKeyHelp openStandardWorkspace standardWorkspaceContents) ('user interface' informUser:during: informUserDuring:) !