Changes in GT for supporting in Pharo 12
This page documents changes that we did in GT for supporting it in Pharo 12.
Some changes are quick fixes that fix an issue, but would be better to review.
RPackage>>#toTagName: is not in Pharo 12 so no need to patch it.
CompiledMethod>>#basicAsMCMethodDefinition
basicAsMCMethodDefinition
<gtPharoPatch: #Pharo>
^ MCMethodDefinition
className: self methodClass instanceSide name
classIsMeta: self isClassSide
selector: self selector
category: self protocol
timeStamp: '' "self stamp"
source: self sourceCode
should use #protocolName instead of #protocol. Before #protocol returned a string, now it returns an object.
Added MetacelloToolBox to releaser
MetacelloToolBox
Object subclass: #MetacelloToolBox
instanceVariableNames: 'project methodSpec'
classVariableNames: ''
package: 'GToolkit-Releaser-BaselineModel-Metacello'
is not much used in Pharo and was removed in https://github.com/pharo-project/pharo/pull/15287. We copied it to releaser for now. We should review how/why we need to use it.
Added MetacelloMCProjectSpec>>#projectClass
projectClass
self className == nil
ifTrue: [ ^ nil ].
^ Smalltalk at: self className asSymbol ifAbsent: [ ]
; commit
we should review why we need it
Update GtRlDependenciesModelBuilder
Object subclass: #GtRlDependenciesModelBuilder
instanceVariableNames: 'projectsByBaselineClass repositoriesByUrl projectsChain'
classVariableNames: ''
package: 'GToolkit-Releaser-BaselineModel-Builder'
In Pharo 12 getting the metacelo version throug MetacelloMCProjectSpec
MetacelloGenericProjectSpec subclass: #MetacelloMCProjectSpec
instanceVariableNames: 'file'
classVariableNames: ''
package: 'Metacello-MC-Specs'
. Instead we get it directly from the baseline class.
Move announcer attribute to Job
Object subclass: #Job
instanceVariableNames: 'block currentValue min max title children isRunning parent process owner announcer'
classVariableNames: ''
package: 'Jobs-Base'
from GtJob
Job subclass: #GtJob
instanceVariableNames: ''
classVariableNames: ''
package: 'GToolkit-Pharo-Coder-UI-Refactorings'
In Pharo 12, Job
Object subclass: #Job
instanceVariableNames: 'block currentValue min max title children isRunning parent process owner announcer'
classVariableNames: ''
package: 'Jobs-Base'
has an announcemt. So we add it to Pharo 10&11 in BaselineOfGToolkitPrerequisites>>#applyPatchForJob
applyPatchForJob
self
fastForPharo13AndPharo12: []
forPharo11: [ Job addSlot: #announcer ]
as we need GtJob
Job subclass: #GtJob
instanceVariableNames: ''
classVariableNames: ''
package: 'GToolkit-Pharo-Coder-UI-Refactorings'
to have its own announcemet.
The hierarchy of the class Protocol
AbstractProtocol subclass: #Protocol
instanceVariableNames: 'name methodSelectors'
classVariableNames: ''
package: 'Kernel-Protocols'
is changed in Pharo 12. There is no more AbstractProtocol, AllProtocol andProtocolOrganizer.
Login to handle the finalization process was extracted from WeakArray
Array weakSubclass: #WeakArray
instanceVariableNames: ''
classVariableNames: 'FinalizationProcess FinalizationSemaphore MournLoopProcess StopRequested StoppedSemaphore'
package: 'Collections-Weak-Base'
.
In Pharo 11 the logic to handle the finalization process is on the class side of WeakArray
Array weakSubclass: #WeakArray
instanceVariableNames: ''
classVariableNames: 'FinalizationProcess FinalizationSemaphore MournLoopProcess StopRequested StoppedSemaphore'
package: 'Collections-Weak-Base'
. In Pharo 12 a dedicated class, FinalizationProcess
Object subclass: #FinalizationProcess
instanceVariableNames: ''
classVariableNames: 'FinalizationSemaphore MournLoopProcess StopRequested StoppedSemaphore TheFinalizationProcess'
package: 'GToolkit-UtilitySystemStubs'
, was added.
One issue is that in Pharo 11, the class WeakArray has an class variable named FinalisationProcess, that is being changed. We add those methods that change the class variable FinalisationProcess using the patch BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray
applyPatchForWeakArray
self
fastForPharo13AndPharo12: []
forPharo11: [
WeakArray
addClassVarNamed: 'MournLoopProcess';
addClassVarNamed: 'StopRequested';
addClassVarNamed: 'StoppedSemaphore';
initialize.
WeakArray class compile:
'stopRequested
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
^ StopRequested ifNil: [ false ]'
classified: 'gt-pharo-patch'.
WeakArray class compile:
'stoppedSemaphore
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
^ StoppedSemaphore ifNil: [ StoppedSemaphore := Semaphore new ]'
classified: 'gt-pharo-patch'.
WeakArray class compile:
'finalizationProcess
"The finalization process arranges to send mourn to each element of the VM''s finalization queue,
which is accessed via primitiveFetchMourner. The VM signals FinalizationSemaphore whenever
the queue is non-empty. This process loops, waiting on the semaphore, fetches the first element
of the queue and then spawns a process at a higher priority to actually send the mourn messages.
If an error occurs in the higher priority mourn loop process then this process will simply spawn
another process, hence ensuring that errors in finalization methods don''t break finalization.
In addition this process also runs the old finalization scheme, supporting clients of the older,
WeakRegistry based scheme. Hopefully this will go away when all clients have moved over."
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
| throttle firstMourner |
throttle := Semaphore new.
[true] whileTrue: [FinalizationSemaphore wait; initSignals.
[firstMourner := self primitiveFetchMourner.
firstMourner notNil] whileTrue:
[MournLoopProcess := [
[ [ self mournLoopWith: firstMourner]
on: Error
fork: [ :ex | ex pass ] ]
ensure: [ throttle signal ].
] newProcess.
MournLoopProcess priority: Processor activePriority + 1.
AsyncProcessProperties
process: MournLoopProcess
property: #parentProcess
put: Processor activeProcess.
MournLoopProcess resume.
throttle wait]]'
classified: 'gt-pharo-patch'.
WeakArray class compile:
'gtSummaryFor: aView
<gtView>
<gtClassView>
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
^ aView columnedList
title: ''Summary'';
priority: 10;
items: [ {
''FinalizationProcess'' -> FinalizationProcess.
''FinalizationSemaphore'' -> FinalizationSemaphore size.
''MournLoopProcess'' -> MournLoopProcess.
''StopRequested'' -> StopRequested.
''StoppedSemaphore'' -> StoppedSemaphore size. } ];
column: ''Item'' text: #key;
column: ''Value'' text: #value;
actionUpdateButton.'
classified: 'gt-pharo-patch'.
WeakArray class compile:
'mournLoopWith: firstMourner
"Send mourn to all the objects available in the mourn queue, starting
with firstMourner which the sender has already extracted for us. If
an error occurs here, it will break this loop but the sender will spawn
another mournLoopWith: so that finalization is not broken by errors in
individual cases."
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
| mourner |
mourner := firstMourner.
[ self stopRequested ifTrue:
[ self stoppedSemaphore signal.
MournLoopProcess := nil.
^ self ].
mourner mourn.
(mourner := self primitiveFetchMourner) notNil] whileTrue.
MournLoopProcess := nil.'
classified: 'gt-pharo-patch'.
WeakArray class
compile: 'restartFinalizationProcess
"kill any old process, just in case"
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
self stopFinalizationProcess.
FinalizationSemaphore := Smalltalk specialObjectsArray at: 42.
StopRequested := false.
FinalizationProcess := [self finalizationProcess]
forkAt: Processor userInterruptPriority.
FinalizationProcess name: ''WeakArray Finalization Process'''
classified: 'gt-pharo-patch'.
WeakArray class
compile: 'shutDown: quitting
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
self stopFinalizationProcess'
classified: 'gt-pharo-patch'.
WeakArray class
compile: 'startUp: resuming
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
self restartFinalizationProcess'
classified: 'gt-pharo-patch'.
WeakArray class
compile: 'stopFinalizationProcess
<gtPharoPatch: #Pharo11>
"DO NOT EDIT HERE, see BaselineOfGToolkitPrerequisites>>#applyPatchForWeakArray"
FinalizationProcess ifNotNil:
[FinalizationProcess terminate.
FinalizationProcess := nil].
(MournLoopProcess isNil or: [ MournLoopProcess isTerminated ])
ifTrue: [ ^ self ].
self assert: self stoppedSemaphore isSignaled not.
StopRequested := true.
StoppedSemaphore wait.'
classified: 'gt-pharo-patch'.
].
only in Pharo 11.
For FinalizationProcess
Object subclass: #FinalizationProcess
instanceVariableNames: ''
classVariableNames: 'FinalizationSemaphore MournLoopProcess StopRequested StoppedSemaphore TheFinalizationProcess'
package: 'GToolkit-UtilitySystemStubs'
we compile the class in Pharo 11 as a patch, and missing class variables in Pharo 12, in BaselineOfGToolkitPrerequisites>>#applyPatchForFinalizationProcess
applyPatchForFinalizationProcess
self
fastForPharo13AndPharo12: [ self applyPatchForFinalizationProcessPharo12Plus ]
forPharo11: [ self applyPatchForFinalizationProcessPharo11 ]
.
UUID
ByteArray variableByteSubclass: #UUID
instanceVariableNames: ''
classVariableNames: ''
package: 'Network-UUID-Base'
changed superclass and structure
In Pharo 11 UUID
ByteArray variableByteSubclass: #UUID
instanceVariableNames: ''
classVariableNames: ''
package: 'Network-UUID-Base'
subclasses ByteArray
ArrayedCollection variableByteSubclass: #ByteArray
instanceVariableNames: ''
classVariableNames: ''
package: 'Collections-Native-Base'
. In Pharo 12 it subclasses Object and has a uuidData slot with the byte array data. In GT it was causing issues due to how we serialize UUID objects. Most changes are limited to:
UUID>>#fromBase64EncodedString:
fromBase64EncodedString: aString64
| uid |
uid := self nilUUID.
self
forPharo12AndNewer: [
(ZnBase64Encoder new
decode: aString64 readStream to: uid uuidData writeStream) ]
forPharo11: [
ZnBase64Encoder new
decode: aString64 readStream to: uid writeStream ].
^ uid
UUID>>#base64Encoded
base64Encoded
^ self
forPharo12AndNewer: [ self uuidData base64Encoded ]
forPharo11: [ super base64Encoded ]
OmEntry
Object subclass: #OmEntry
instanceVariableNames: 'tags content'
classVariableNames: ''
package: 'Ombu-Entries'
missing time
When OmEntry
Object subclass: #OmEntry
instanceVariableNames: 'tags content'
classVariableNames: ''
package: 'Ombu-Entries'
objects are created in EpLog>>#addEntryWith:tags:
addEntryWith: anEvent tags: blockClosureForCustomTags
"Add an event with the specified tags"
| newEntry |
newEntry := OmEntry content: anEvent.
"add tags"
newEntry tags
at: self class priorReferenceKey put: self headReference;
in: blockClosureForCustomTags.
"write the new entry"
store newEntry: newEntry.
"update caches with the new entry"
self cacheEntry: newEntry.
self announceAdded: newEntry.
^ newEntry
no time is set in Pharo 12. We are using them in OmEntry>>#gtTime
gtTime
^ self tagAt: EpLog timeKey
.
Icons for EpEvent
Object subclass: #EpEvent
instanceVariableNames: ''
classVariableNames: ''
package: 'Epicea-Model'
entries
In Pharo 12 a different visitor it used to just return the name of an icon instead of a Form object. The patch is in GtEpicea>>#iconForEpiceaChange:
iconForEpiceaChange: anEpChange
^ self
forPharo12AndNewer: [
Smalltalk ui icons iconNamed: (anEpChange accept: EpIconNameVisitor new) ]
forPharo11: [
anEpChange accept: EpIconVisitor new ]
.
Use CodeError instead of OCSemanticWarning.
Error handling changed in the compiler. Checking for those errors in coder in GtPharoSourceCoder>>#handleCompilerErrorsDuring:inContext:
handleCompilerErrorsDuring: aBlock inContext: aGtPharoSourceCoderEvaluationContext
^ [ aBlock value.
true ]
on: self compilerErrorsToHandle
do: [ :ex |
self
notifyParseError: ex
requesterObject: aGtPharoSourceCoderEvaluationContext requesterObject.
ex return: false ]
should use CodeError in Pharo 12.
Restructuring of OCUndeclaredVariableWarning
OCSemanticWarning subclass: #OCUndeclaredVariableWarning
instanceVariableNames: ''
classVariableNames: ''
package: 'OpalCompiler-Core-Exception'
In Pharo 11 OCUndeclaredVariableWarning
OCSemanticWarning subclass: #OCUndeclaredVariableWarning
instanceVariableNames: ''
classVariableNames: ''
package: 'OpalCompiler-Core-Exception'
contains the ast node and the logic to repair the code.
In Pharo 12, the warning contains a notice as an instance of OCUndeclaredVariableNotice that is a kind of RBNotice, representing error and warning information on a AST node.
The undecrared variable notice returns then OCCodeReparator that contains the logic for doing the repair that was before in the warning.
Removed requestor from CompilationContext
Object subclass: #CompilationContext
instanceVariableNames: 'requestor failBlock logged compiledMethod options environment productionEnvironment parserClass semanticAnalyzerClass astTranslatorClass bytecodeGeneratorClass compiledMethodTrailer encoderClass astTransformPlugins astParseTransformPlugins requestorScopeClass bindings compiledMethodClass semanticScope'
classVariableNames: 'DefaultOptions DefaultParseTransformationPlugins DefaultTransformationPlugins'
package: 'OpalCompiler-Core-FrontEnd'
.
Was moved to OpalCompiler
Object subclass: #OpalCompiler
instanceVariableNames: 'ast source compilationContext compilationContextClass'
classVariableNames: ''
package: 'OpalCompiler-Core-FrontEnd'
. It was used in BrRBTextStyler>>#privateStyle:
privateStyle: aText
| ast |
ast := self parseWithSemanticAnalysis: aText.
self style: aText ast: ast.
self extraStyle: aText ast: ast.
^ aText
Setter is still OpalCompiler>>#requestor:
requestor: aRequestor
self compilationContext requestor: aRequestor
Clipboard
Object subclass: #Clipboard
instanceVariableNames: 'contents recent'
classVariableNames: 'Default'
package: 'Morphic-Core-Utilities'
recent items
The variable to hold the history changed from recent to recentClippings.
WorkingSession
Object subclass: #WorkingSession
instanceVariableNames: 'manager deferredStartupActions id creationTime properties'
classVariableNames: ''
package: 'System-SessionManager-Utilities'
does not have an id and creationTime in Pharo 12
DateAndTime
Magnitude subclass: #DateAndTime
instanceVariableNames: 'seconds offset julianDayNumber nanos'
classVariableNames: 'ClockProvider LocalTimeZoneCache'
poolDictionaries: 'ChronologyConstants'
package: 'Kernel-Chronology'
validation
DateAndTime
Magnitude subclass: #DateAndTime
instanceVariableNames: 'seconds offset julianDayNumber nanos'
classVariableNames: 'ClockProvider LocalTimeZoneCache'
poolDictionaries: 'ChronologyConstants'
package: 'Kernel-Chronology'
has more validation when parsed from a string. The code below fails in Pharo 12
DateAndTime fromString: '2023/10/01 09:00:00+00:00'.