eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'ClassBuilder':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: ClassBuilder


Inheritance:

   Object
   |
   +--ClassBuilder

Package:
stx:libbasic
Category:
Kernel-Support
Version:
rev: 1.163 date: 2019/08/15 12:07:05
user: cg
file: ClassBuilder.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


an old, ugly beast.
instances are temporarily created to figure out,
which methods and which subclasses need to be recompiled whenever a class's definition
changes.
For fast turn around times, it is good to recompile the smallest needed amount.
(However, in the meantime, so many checks and small-lints and others are watching for
 such changes, that recompilation gets a little slow at times.
 Also, the more browsers you have open, which react and research on changes,
 the slower you get)

Code here is ugly and hard to maintain.
Keep your fingers away...



Class protocol:

change & update
o  initialize
(comment from inherited method)
called only once - initialize signals

o  update: something with: aParameter from: changedObject
keep track of the namespace->classnames cache

checks
o  checkForAliasesOf: oldClass with: newClass
oldClass changed its identity (now use newClass).
check if there are any global aliases, which should also be changed

o  differentInstanceVariableOffsetsIn: class1 and: class2
return a set of instance variable names which have different
positions in class1 and class2.
Also, variables which are only present in one class are returned.
This is used to find methods which need recompilation after a
change in the instance variable layout.

usage example(s):

     View class 
        differentInstanceVariableOffsetsIn:View
                                       and:StandardSystemView
     View class 
        differentInstanceVariableOffsetsIn:Object 
                                       and:Point 

recompiling
o  copyInvalidatedMethodsFrom: oldClass for: newClass
copy all methods from oldClass to newClass and change their code
to a trap method reporting an error.
This is done when a class has changed its layout or inheritance,
before recompilation is attempted.
This allows us to keep the source while trapping uncompilable (due to
now undefined instvars) methods. Later compilation of these methods will show
an error on the transcript and lead to the debugger once called.

o  copyInvalidatedMethodsFrom: oldClass for: newClass accessingAny: setOfNames
copy all methods from oldClass to newClass. Those methods accessing
a variable in setOfNames will be copied as invalid method, leading to
a trap when its executed. This is used when a class has changed its
layout for all methods which are affected by the change.

o  copyInvalidatedMethodsFrom: oldClass for: newClass accessingAny: setOfNames orSuper: superBoolean
copy all methods from oldClass to newClass.
Those methods accessing a variable in setOfNames will be copied as invalid method,
leading to a trap when executed. If superBoolean is true, this is also done
for methods accessing super. This is used when a class has changed its
layout for all methods which are affected by the change.

o  copyMethodsFrom: oldClass for: newClass
copy all methods from oldClass to newClass.
This is used for class-methods when a class has changed, but its metaclass is
unaffected (i.e. classVars/inheritance have not changed) so there is no need
to recompile the class methods.

o  recompileGlobalAccessorsTo: aGlobalKey in: aNamespace except: someClass
when a new class enters a namespace, all accessors to the same-named
class in that namespace must be recompiled.
This is required because if some global Foo is used inside a namespace, and that namespace
does not contain a Foo, that Foo refers to Smalltalk::Foo.
However when we finally load a Foo, all those refs should now refer to Namespace::Foo.
Because that is used heavily during package loading (for the same namespace), cache it.

o  recompileMachineCodeMethodsIn: aClass
recompile all machine-code methods in aClass.


Instance protocol:

Compatibility-Squeak
o  name: newName inEnvironment: aSystemDictionaryOrClass subclassOf: aClass type: type instanceVariableNames: stringOfInstVarNames classVariableNames: stringOfClassVarNames poolDictionaries: stringOfPoolNames category: categoryString
this returns the created class; it is not a simple accessor

accessing
o  classClass

o  classClass: aClass

o  metaclass: metaclassOrASubclassOfIt

o  name: newName inEnvironment: aSystemDictionaryOrClass subclassOf: aClass instanceVariableNames: stringOfInstVarNames variable: variableBoolean words: wordsBoolean pointers: pointersBoolean classVariableNames: stringOfClassVarNames poolDictionaries: stringOfPoolNames category: categoryString comment: commentString changed: changedBoolean classInstanceVariableNames: stringOfClassInstVarNamesOrNil
Allowing non-booleans as variableBoolean

o  oldMetaclass: aMetaclass instanceVariableNames: stringOfInstVarNames

building
o  buildClass
this is the main workhorse for installing new classes - special care
has to be taken, when changing an existing classes definition. In this
case, some or all of the methods and subclass-methods have to be
recompiled.
Also, the old class(es) are still kept (but not accessible as a global),
to allow existing instances some life.
This might change in the future.

o  newSubclassOf: baseClass type: typeOfClass instanceVariables: instanceVariables from: oldClassArg
anonymous classes can be built with this entry

building-helpers
o  changeReferencesFrom: oldClass to: newClass
answer := OptionBox

o  copyClassInstanceVariablesFrom: oldClass to: newClass
copy over classInstanceVariables

o  determineNewName
does the name imply a nameSpace ?

o  environmentChanged: how with: argument

o  environmentChangedOrganization

o  fixMethodsIn: newClass
care for class methods ...

o  flagsForVariable: variable pointers: pointers words: words
Allowing non-booleans as variable is a hack for STX / ST80 compatibility:

o  handleEasyNewClass: newClass
instance layout remains the same.
We only have to recompile methods which access changed class variables,
changed pool variables.

o  handleHardNewClass: newClass
instance layout has changed.
We have to recompile methods where the slot-index of any accessed instvar is different,
(in addition to those which access changed class variables, changed pool variables, etc.)

o  handleNewlyCreatedClass: newClass
comment notNil ifTrue:[

o  instantiateMetaclass
create the metaclass proper

o  instantiateNewClassFrom: newMetaclass
create the class proper

o  namesInPoolNamed: poolName ofClass: aClass
ns can be a owning class or a real nameSpace or Smalltalk

o  rebuildForChangedClassInstanceVariables
only called for metaclasses.
changing / adding class-inst vars -
this actually creates a new metaclass and class, leaving the original
classes around as obsolete classes. This may also be true for all subclasses,
if class instance variables are added/removed.

Existing instances become an instance of the new class
(which can be done without become, by changing their class only, because
the instance-layout has not changed).

However, if the old class is referenced somewhere (in a collection),
that reference will still point to the old, now obsolete class.
Time will show, if that is a problem and will be fixed.

o  setPackageInNewClass: newClass fromOld: oldClass
set the new classes package

o  setupNewClass: newClass fromOld: oldClass
self flagsForVariable:variable pointers:pointers words:words.

checks
o  checkClassName
check if the given name implies a (sub-) namespace

o  checkConventionsFor: className subClassOf: aClass instVarNames: instVarNameString classVarNames: classVarNameString
Check for some 'considered bad-style' things, like lower case names.
NOTICE:
I don't like the confirmers below - we need a notifying: argument, to give
the outer codeview a chance to highlight the error.
(but that's how its defined in the book - maybe I will change it anyway).

o  checkForCircularDefinitionFrom: oldClass

o  checkInstvarRedefsWith: stringOfInstVarNames subclassOf: aClass old: oldClass name: newName
check for instVar redef of superClass instVars

o  checkValidPools
check for invalid subclassing of UndefinedObject and SmallInteger

o  checkValidSubclassing
check for invalid subclassing of UndefinedObject and SmallInteger

o  checkValidVarNamesFor: className subClassOf: aClass instVarNames: instVarNameString classVarNames: classVarNameString
Check for some 'considered bad-style' things, like lower case names.
NOTICE:
I don't like the confirmers below - we need a notifying: argument, or a
notifierSignal to give the outer codeview a chance to highlight the error.
(but that's how its defined in the book - maybe I will change it anyway).



ST/X 7.2.0.0; WebServer 1.670 at bd0aa1f87cdd.unknown:8081; Thu, 25 Apr 2024 14:19:49 GMT