58 Late addition: above comment is no longer true - I have made now almost |
58 Late addition: above comment is no longer true - I have made now almost |
59 all Demos & Goodies be autoloaded ... even for big systems. |
59 all Demos & Goodies be autoloaded ... even for big systems. |
60 |
60 |
61 [class variables:] |
61 [class variables:] |
62 |
62 |
63 LazyLoading <Boolean> if true, the loaded classes |
63 LazyLoading <Boolean> if true, the loaded classes |
64 methods will NOT be compiled at |
64 methods will NOT be compiled at |
65 autoload time, but instead when |
65 autoload time, but instead when |
66 first called. This allows for a |
66 first called. This allows for a |
67 faster load. However, expect short |
67 faster load. However, expect short |
68 pauses later when the methods are |
68 pauses later when the methods are |
69 first executed. |
69 first executed. |
70 |
70 |
71 AutoloadFailedSignal <Signal> signal raised if an autoloaded |
71 AutoloadFailedSignal <Signal> signal raised if an autoloaded |
72 classes source is not available. |
72 classes source is not available. |
73 |
73 |
74 LoadedClasses <Collection> set of classes that heve been |
74 LoadedClasses <Collection> set of classes that heve been |
75 autoloaded (for later unload) |
75 autoloaded (for later unload) |
76 |
76 |
77 [see also:] |
77 [see also:] |
78 Smalltalk |
78 Smalltalk |
79 |
79 |
80 [author:] |
80 [author:] |
81 Claus Gittinger |
81 Claus Gittinger |
82 " |
82 " |
83 ! ! |
83 ! ! |
84 |
84 |
85 !Autoload class methodsFor:'initialization'! |
85 !Autoload class methodsFor:'initialization'! |
86 |
86 |
87 initialize |
87 initialize |
88 "initialize the failure-signal" |
88 "initialize the failure-signal" |
89 |
89 |
90 AutoloadFailedSignal isNil ifTrue:[ |
90 AutoloadFailedSignal isNil ifTrue:[ |
91 LazyLoading := false. |
91 LazyLoading := false. |
92 |
92 |
93 AutoloadFailedSignal := Object errorSignal newSignalMayProceed:true. |
93 AutoloadFailedSignal := Object errorSignal newSignalMayProceed:true. |
94 AutoloadFailedSignal nameClass:self message:#autoloadFailedSignal. |
94 AutoloadFailedSignal nameClass:self message:#autoloadFailedSignal. |
95 AutoloadFailedSignal notifierString:'autoload failed '. |
95 AutoloadFailedSignal notifierString:'autoload failed '. |
96 |
96 |
97 self setSuperclass:nil. |
97 self setSuperclass:nil. |
98 ObjectMemory flushCaches. |
98 ObjectMemory flushCaches. |
99 ] |
99 ] |
100 |
100 |
101 "Modified: 20.5.1997 / 19:06:25 / cg" |
101 "Modified: 20.5.1997 / 19:06:25 / cg" |
102 ! ! |
102 ! ! |
103 |
103 |
174 in Smalltalk |
174 in Smalltalk |
175 (knowing the details of loading here is no good coding style) |
175 (knowing the details of loading here is no good coding style) |
176 " |
176 " |
177 fileName := Smalltalk fileNameForClass:myName. |
177 fileName := Smalltalk fileNameForClass:myName. |
178 (ObjectFileLoader notNil and:[Smalltalk loadBinaries]) ifTrue:[ |
178 (ObjectFileLoader notNil and:[Smalltalk loadBinaries]) ifTrue:[ |
179 (nm := Smalltalk libraryFileNameOfClass:myName) notNil ifTrue:[ |
179 (nm := Smalltalk libraryFileNameOfClass:myName) notNil ifTrue:[ |
180 nm := nm , ' (a classLibrary, possibly including more classes)' |
180 nm := nm , ' (a classLibrary, possibly including more classes)' |
181 ] ifFalse:[ |
181 ] ifFalse:[ |
182 nm := Smalltalk getBinaryFileName:(fileName , '.so'). |
182 nm := Smalltalk getBinaryFileName:(fileName , '.so'). |
183 nm isNil ifTrue:[ |
183 nm isNil ifTrue:[ |
184 nm := Smalltalk getBinaryFileName:(fileName , '.o') |
184 nm := Smalltalk getBinaryFileName:(fileName , '.o') |
185 ]. |
185 ]. |
186 nm notNil ifTrue:[ |
186 nm notNil ifTrue:[ |
187 nm := nm , ' (a classBinary)' |
187 nm := nm , ' (a classBinary)' |
188 ] |
188 ] |
189 ]. |
189 ]. |
190 ]. |
190 ]. |
191 nm isNil ifTrue:[ |
191 nm isNil ifTrue:[ |
192 nm := Smalltalk getFileInFileName:(fileName , '.st'). |
192 nm := Smalltalk getFileInFileName:(fileName , '.st'). |
193 nm isNil ifTrue:[ |
193 nm isNil ifTrue:[ |
194 nm := Smalltalk getSourceFileName:(fileName , '.st'). |
194 nm := Smalltalk getSourceFileName:(fileName , '.st'). |
195 ]. |
195 ]. |
196 ]. |
196 ]. |
197 nm notNil ifTrue:[ |
197 nm notNil ifTrue:[ |
198 aStream cr; nextPutLine:'When accessed, ' , myName , ' will automatically be loaded'. |
198 aStream cr; nextPutLine:'When accessed, ' , myName , ' will automatically be loaded'. |
199 aStream nextPutLine:'from: '; spaces:4; nextPutAll:nm. |
199 aStream nextPutLine:'from: '; spaces:4; nextPutAll:nm. |
200 nm asFilename isSymbolicLink ifTrue:[ |
200 nm asFilename isSymbolicLink ifTrue:[ |
201 aStream cr; cr. |
201 aStream cr; cr. |
202 aStream nextPutLine:'which is a link to: '; spaces:4; |
202 aStream nextPutLine:'which is a link to: '; spaces:4; |
203 nextPutAll:(nm asFilename linkInfo path). |
203 nextPutAll:(nm asFilename linkInfo path). |
204 ] |
204 ] |
205 ] ifFalse:[ |
205 ] ifFalse:[ |
206 aStream cr; nextPutLine:'There is currently no file to load ' , myName , ' from.'; cr. |
206 aStream cr; nextPutLine:'There is currently no file to load ' , myName , ' from.'; cr. |
207 |
207 |
208 (mgr := Smalltalk at:#SourceCodeManager) notNil ifTrue:[ |
208 (mgr := Smalltalk at:#SourceCodeManager) notNil ifTrue:[ |
209 classFileName := Smalltalk fileNameForClass:myName. |
209 classFileName := Smalltalk fileNameForClass:myName. |
210 packageDir := Smalltalk sourceDirectoryNameOfClass:myName. |
210 packageDir := Smalltalk sourceDirectoryNameOfClass:myName. |
211 ]. |
211 ]. |
212 (classFileName notNil and:[packageDir notNil]) ifTrue:[ |
212 (classFileName notNil and:[packageDir notNil]) ifTrue:[ |
213 aStream nextPutAll:'When accessed, I''ll ask the sourceCodeManager to load the code |
213 aStream nextPutAll:'When accessed, I''ll ask the sourceCodeManager to load the code |
214 from "' , classFileName , '.st" in the "' , packageDir , '" package.'. |
214 from "' , classFileName , '.st" in the "' , packageDir , '" package.'. |
215 ] ifFalse:[ |
215 ] ifFalse:[ |
216 aStream nextPutAll:'When accessed, an error will be reported.'. |
216 aStream nextPutAll:'When accessed, an error will be reported.'. |
217 ] |
217 ] |
218 ]. |
218 ]. |
219 aStream cr; nextPutAll:'"'. |
219 aStream cr; nextPutAll:'"'. |
220 |
220 |
221 "Modified: 30.12.1996 / 17:25:15 / cg" |
221 "Modified: 30.12.1996 / 17:25:15 / cg" |
222 "Created: 5.1.1997 / 14:31:33 / cg" |
222 "Created: 5.1.1997 / 14:31:33 / cg" |
245 |
245 |
246 autoload |
246 autoload |
247 "use this to force loading |
247 "use this to force loading |
248 - it is defined a noop in all non-autoloading classes" |
248 - it is defined a noop in all non-autoloading classes" |
249 |
249 |
250 |mySelf myName newClass oldMeta project prevMode package| |
250 |mySelf myName myNameSpace newClass oldMeta project prevMode package| |
251 |
251 |
252 mySelf := self. |
252 mySelf := self. |
253 myName := self name asSymbol. |
253 myName := self name asSymbol. |
|
254 myNameSpace := self nameSpace. |
254 |
255 |
255 "remove myself - to avoid recompilation" |
256 "remove myself - to avoid recompilation" |
256 Smalltalk at:myName put:nil. |
257 Smalltalk at:myName put:nil. |
257 |
258 |
258 "load it" |
259 "load it" |
259 (Object infoPrinting and:[Smalltalk silentLoading ~~ true]) ifTrue:[ |
260 (Object infoPrinting and:[Smalltalk silentLoading ~~ true]) ifTrue:[ |
260 Transcript showCR:('autoloading ', myName , ' ...'); endEntry. |
261 Transcript showCR:('autoloading ', myName , ' ...'); endEntry. |
261 ]. |
262 ]. |
262 |
263 |
263 [ |
264 [ |
264 prevMode := ClassCategoryReader sourceMode. |
265 prevMode := ClassCategoryReader sourceMode. |
265 "/ |
266 "/ |
266 "/ no- do not do this; it may lead to trouble ... |
267 "/ no- do not do this; it may lead to trouble ... |
267 "/ ClassCategoryReader sourceMode:#reference. |
268 "/ ClassCategoryReader sourceMode:#reference. |
268 |
269 |
269 "/ |
270 "/ |
270 "/ in order to not get a package of private (or whatever), |
271 "/ in order to not get a package of private (or whatever), |
271 "/ temporarily set the currentProject to nil. |
272 "/ temporarily set the currentProject to nil. |
272 "/ we will later set the classes package to something useful |
273 "/ we will later set the classes package to something useful |
273 "/ |
274 "/ |
274 Project notNil ifTrue:[ |
275 Project notNil ifTrue:[ |
275 project := Project current. |
276 project := Project current. |
276 Project setProject:nil. |
277 Project setProject:nil. |
277 ]. |
278 ]. |
278 |
279 |
279 Class nameSpaceQuerySignal answer:Smalltalk |
280 Class nameSpaceQuerySignal answer:myNameSpace "Smalltalk" |
280 do:[ |
281 do:[ |
281 Smalltalk fileInClass:myName initialize:false lazy:LazyLoading. |
282 Smalltalk fileInClass:myName initialize:false lazy:LazyLoading. |
282 ]. |
283 ]. |
283 ClassCategoryReader sourceMode:prevMode. |
284 ClassCategoryReader sourceMode:prevMode. |
284 project notNil ifTrue:[ |
285 project notNil ifTrue:[ |
285 Project setProject:project. |
286 Project setProject:project. |
286 ]. |
287 ]. |
287 ] valueOnUnwindDo:[ |
288 ] valueOnUnwindDo:[ |
288 ClassCategoryReader sourceMode:prevMode. |
289 ClassCategoryReader sourceMode:prevMode. |
289 project notNil ifTrue:[ |
290 project notNil ifTrue:[ |
290 Project setProject:project. |
291 Project setProject:project. |
291 ]. |
292 ]. |
292 Smalltalk at:myName put:mySelf. |
293 Smalltalk at:myName put:mySelf. |
293 ]. |
294 ]. |
294 |
295 |
295 "did it work ?" |
296 "did it work ?" |
296 newClass := Smalltalk at:myName. |
297 newClass := Smalltalk at:myName. |
297 Smalltalk at:myName put:mySelf. "will be undone by become:" |
298 Smalltalk at:myName put:mySelf. "will be undone by become:" |
298 |
299 |
299 "no - report the error" |
300 "no - report the error" |
300 newClass isNil ifTrue:[ |
301 newClass isNil ifTrue:[ |
301 " |
302 " |
302 this signal is raised, if an autoloaded class |
303 this signal is raised, if an autoloaded class |
303 cannot be loaded. Usually, this happends when |
304 cannot be loaded. Usually, this happends when |
304 some sourcefile is missing, not readable or if |
305 some sourcefile is missing, not readable or if |
305 an entry is missing in the abbreviation file. |
306 an entry is missing in the abbreviation file. |
306 Check for a readable file named <myName>.st |
307 Check for a readable file named <myName>.st |
307 in the 'source' directory and (if its a long fileName) |
308 in the 'source' directory and (if its a long fileName) |
308 for a corresponding entry in the abbreviation file |
309 for a corresponding entry in the abbreviation file |
309 'include/abbrev.stc'. |
310 'include/abbrev.stc'. |
310 Finally, your searchpath could be set wrong - |
311 Finally, your searchpath could be set wrong - |
311 both 'source' and 'include' directories must be found in |
312 both 'source' and 'include' directories must be found in |
312 one of the directories named in systemPath. |
313 one of the directories named in systemPath. |
313 |
314 |
314 In the debugger, press 'abort' to continue execution. |
315 In the debugger, press 'abort' to continue execution. |
315 " |
316 " |
316 AutoloadFailedSignal |
317 AutoloadFailedSignal |
317 raiseRequestWith:self |
318 raiseRequestWith:self |
318 errorString:('autoload of ' , myName , ' failed'). |
319 errorString:('autoload of ' , myName , ' failed'). |
319 ^ nil |
320 ^ nil |
320 ]. |
321 ]. |
321 |
322 |
322 "/ |
323 "/ |
323 "/ autoloaded classes get their package from the revision (if present) |
324 "/ autoloaded classes get their package from the revision (if present) |
324 "/ this only happens with autoloaded sourceFiles which have no package |
325 "/ this only happens with autoloaded sourceFiles which have no package |
326 "/ If there is no such information, give it my package (if I have one) |
327 "/ If there is no such information, give it my package (if I have one) |
327 "/ |
328 "/ |
328 newClass setPackageFromRevision. |
329 newClass setPackageFromRevision. |
329 (newClass package isNil |
330 (newClass package isNil |
330 or:[newClass package = 'no package']) ifTrue:[ |
331 or:[newClass package = 'no package']) ifTrue:[ |
331 package := self package. |
332 package := self package. |
332 (package notNil and:[package ~= 'no package']) |
333 (package notNil and:[package ~= 'no package']) |
333 ifTrue:[ |
334 ifTrue:[ |
334 newClass setPackage:package. |
335 newClass setPackage:package. |
335 ]. |
336 ]. |
336 ]. |
337 ]. |
337 |
338 |
338 LoadedClasses isNil ifTrue:[ |
339 LoadedClasses isNil ifTrue:[ |
339 LoadedClasses := IdentitySet new. |
340 LoadedClasses := IdentitySet new. |
340 ]. |
341 ]. |
341 LoadedClasses add:newClass. |
342 LoadedClasses add:newClass. |
342 |
343 |
343 "wow - it worked. now the big trick ..." |
344 "wow - it worked. now the big trick ..." |
344 |
345 |
490 |
491 |
491 |newClass sel args| |
492 |newClass sel args| |
492 |
493 |
493 "take care: subclassing Autoload must still be possible" |
494 "take care: subclassing Autoload must still be possible" |
494 (self == Autoload) ifTrue:[ |
495 (self == Autoload) ifTrue:[ |
495 ^ super |
496 ^ super |
496 subclass:nameSymbol |
497 subclass:nameSymbol |
497 instanceVariableNames:instVarNames |
498 instanceVariableNames:instVarNames |
498 classVariableNames:cVarNames |
499 classVariableNames:cVarNames |
499 poolDictionaries:poolDicts |
500 poolDictionaries:poolDicts |
500 category:cat |
501 category:cat |
501 inEnvironment:aNameSpace |
502 inEnvironment:aNameSpace |
502 ]. |
503 ]. |
503 |
504 |
504 newClass := self autoload. |
505 newClass := self autoload. |
505 sel := thisContext selector. |
506 sel := thisContext selector. |
506 args := thisContext args. |
507 args := thisContext args. |
507 newClass notNil ifTrue:[ |
508 newClass notNil ifTrue:[ |
508 ^ newClass perform:sel withArguments:args |
509 ^ newClass perform:sel withArguments:args |
509 ]. |
510 ]. |
510 ^ nil |
511 ^ nil |
511 |
512 |
512 "Created: 8.2.1997 / 19:42:47 / cg" |
513 "Created: 8.2.1997 / 19:42:47 / cg" |
513 ! |
514 ! |
518 |
519 |
519 |newClass sel args| |
520 |newClass sel args| |
520 |
521 |
521 "take care: subclassing Autoload must still be possible" |
522 "take care: subclassing Autoload must still be possible" |
522 (self == Autoload) ifTrue:[ |
523 (self == Autoload) ifTrue:[ |
523 ^ super |
524 ^ super |
524 subclass:nameSymbol |
525 subclass:nameSymbol |
525 instanceVariableNames:instVarNames |
526 instanceVariableNames:instVarNames |
526 classVariableNames:cVarNames |
527 classVariableNames:cVarNames |
527 poolDictionaries:poolDicts |
528 poolDictionaries:poolDicts |
528 privateIn:owningClass |
529 privateIn:owningClass |
529 ]. |
530 ]. |
530 |
531 |
531 newClass := self autoload. |
532 newClass := self autoload. |
532 sel := thisContext selector. |
533 sel := thisContext selector. |
533 args := thisContext args. |
534 args := thisContext args. |
534 newClass notNil ifTrue:[ |
535 newClass notNil ifTrue:[ |
535 ^ newClass perform:sel withArguments:args |
536 ^ newClass perform:sel withArguments:args |
536 ]. |
537 ]. |
537 ^ nil |
538 ^ nil |
538 |
539 |
539 "Created: 8.2.1997 / 19:42:47 / cg" |
540 "Created: 8.2.1997 / 19:42:47 / cg" |
540 ! ! |
541 ! ! |