changeset 13463 | 7c98583d98c8 |
parent 13422 | b43a8a47037c |
child 13567 | fe6564553977 |
13462:2d4683974fc7 | 13463:7c98583d98c8 |
---|---|
1 " |
1 " |
2 COPYRIGHT (c) 1989 by Claus Gittinger |
2 COPYRIGHT (c) 1989 by Claus Gittinger |
3 All Rights Reserved |
3 All Rights Reserved |
4 |
4 |
5 This software is furnished under a license and may be used |
5 This software is furnished under a license and may be used |
6 only in accordance with the terms of that license and with the |
6 only in accordance with the terms of that license and with the |
7 inclusion of the above copyright notice. This software may not |
7 inclusion of the above copyright notice. This software may not |
8 be provided or otherwise made available to, or used by, any |
8 be provided or otherwise made available to, or used by, any |
31 !Method class methodsFor:'documentation'! |
31 !Method class methodsFor:'documentation'! |
32 |
32 |
33 copyright |
33 copyright |
34 " |
34 " |
35 COPYRIGHT (c) 1989 by Claus Gittinger |
35 COPYRIGHT (c) 1989 by Claus Gittinger |
36 All Rights Reserved |
36 All Rights Reserved |
37 |
37 |
38 This software is furnished under a license and may be used |
38 This software is furnished under a license and may be used |
39 only in accordance with the terms of that license and with the |
39 only in accordance with the terms of that license and with the |
40 inclusion of the above copyright notice. This software may not |
40 inclusion of the above copyright notice. This software may not |
41 be provided or otherwise made available to, or used by, any |
41 be provided or otherwise made available to, or used by, any |
72 which is identified as executable (assuming that the first instance variable |
72 which is identified as executable (assuming that the first instance variable |
73 is the machine-code address) - this allows for easy future extension. |
73 is the machine-code address) - this allows for easy future extension. |
74 |
74 |
75 [Instance variables:] |
75 [Instance variables:] |
76 |
76 |
77 source <String> the source itself (if sourcePosition isNil) |
77 source <String> the source itself (if sourcePosition isNil) |
78 or the fileName where the source is found |
78 or the fileName where the source is found |
79 |
79 |
80 sourcePosition <Integer> the position of the methods chunk in the file |
80 sourcePosition <Integer> the position of the methods chunk in the file |
81 |
81 |
82 category <Symbol> the methods category |
82 category <Symbol> the methods category |
83 package <Symbol> the package, in which the methods was defined |
83 package <Symbol> the package, in which the methods was defined |
84 mclass <Class> the class in which I am defined |
84 mclass <Class> the class in which I am defined |
85 indexed slots literals |
85 indexed slots literals |
86 |
86 |
87 [Class variables:] |
87 [Class variables:] |
88 |
88 |
89 PrivateMethodSignal raised on privacy violation (see docu) |
89 PrivateMethodSignal raised on privacy violation (see docu) |
90 |
90 |
91 LastFileReference weak reference to the last sourceFile |
91 LastFileReference weak reference to the last sourceFile |
92 LastSourceFileName to speedup source access via NFS |
92 LastSourceFileName to speedup source access via NFS |
93 |
93 |
94 WARNING: layout known by compiler and runtime system - dont change |
94 WARNING: layout known by compiler and runtime system - dont change |
95 |
95 |
96 [author:] |
96 [author:] |
97 Claus Gittinger |
97 Claus Gittinger |
98 " |
98 " |
99 ! |
99 ! |
100 |
100 |
101 dynamicMethods |
101 dynamicMethods |
102 " |
102 " |
151 This interface, the implementation and the rules for when a privacy violation |
151 This interface, the implementation and the rules for when a privacy violation |
152 may change (in case of some ANSI standard being defined). |
152 may change (in case of some ANSI standard being defined). |
153 Be warned and send me suggestions & critics (constructive ;-) |
153 Be warned and send me suggestions & critics (constructive ;-) |
154 |
154 |
155 Late note (Feb 2000): |
155 Late note (Feb 2000): |
156 the privacy feature has new been in ST/X for some years and was NOT heavily |
156 the privacy feature has new been in ST/X for some years and was NOT heavily |
157 used - neither at eXept, nor by customers. |
157 used - neither at eXept, nor by customers. |
158 In Smalltalk, it seems to be a very questionable feature, actually limiting |
158 In Smalltalk, it seems to be a very questionable feature, actually limiting |
159 code reusability. |
159 code reusability. |
160 The privacy features are left in the system to demonstrate that it can be |
160 The privacy features are left in the system to demonstrate that it can be |
161 done in Smalltalk (for religious C++ fans ... to avoid useless discussions) |
161 done in Smalltalk (for religious C++ fans ... to avoid useless discussions) |
162 (the check is not expensive, w.r.t. the VM runtime behavior). |
162 (the check is not expensive, w.r.t. the VM runtime behavior). |
163 " |
163 " |
164 ! ! |
164 ! ! |
165 |
165 |
166 !Method class methodsFor:'initialization'! |
166 !Method class methodsFor:'initialization'! |
167 |
167 |
168 initialize |
168 initialize |
169 "create signals" |
169 "create signals" |
170 |
170 |
171 PrivateMethodSignal isNil ifTrue:[ |
171 PrivateMethodSignal isNil ifTrue:[ |
172 "EXPERIMENTAL" |
172 "EXPERIMENTAL" |
173 PrivateMethodSignal := ExecutionError newSignalMayProceed:true. |
173 PrivateMethodSignal := ExecutionError newSignalMayProceed:true. |
174 PrivateMethodSignal nameClass:self message:#privateMethodSignal. |
174 PrivateMethodSignal nameClass:self message:#privateMethodSignal. |
175 PrivateMethodSignal notifierString:'attempt to execute private/protected method'. |
175 PrivateMethodSignal notifierString:'attempt to execute private/protected method'. |
176 ]. |
176 ]. |
177 |
177 |
178 LastFileLock isNil ifTrue:[ |
178 LastFileLock isNil ifTrue:[ |
179 LastFileLock := RecursionLock new name:'Method-LastFile'. |
179 LastFileLock := RecursionLock new name:'Method-LastFile'. |
180 LastMethodSourcesLock := RecursionLock new name:'Method-LastMethodSources'. |
180 LastMethodSourcesLock := RecursionLock new name:'Method-LastMethodSources'. |
181 |
181 |
182 "LastFileReference used to be a WeakArray. The problem was, that |
182 "LastFileReference used to be a WeakArray. The problem was, that |
183 during some operations (generating project definition methods), lots of |
183 during some operations (generating project definition methods), lots of |
184 methods and classes are accessed. GC (scavenge) is done heavily, |
184 methods and classes are accessed. GC (scavenge) is done heavily, |
185 while finalization is a low prio process, so that the file limit |
185 while finalization is a low prio process, so that the file limit |
186 is reached before finalization did close the old streams." |
186 is reached before finalization did close the old streams." |
187 LastFileReference := Array new:1. |
187 LastFileReference := Array new:1. |
188 LastFileReference at:1 put:nil. |
188 LastFileReference at:1 put:nil. |
189 ]. |
189 ]. |
190 |
190 |
191 CompilationLock := RecursionLock new name:'MethodCompilation'. |
191 CompilationLock := RecursionLock new name:'MethodCompilation'. |
192 |
192 |
193 "Modified: 22.4.1996 / 16:34:38 / cg" |
193 "Modified: 22.4.1996 / 16:34:38 / cg" |
194 "Modified: 3.1.1997 / 16:58:16 / stefan" |
194 "Modified: 3.1.1997 / 16:58:16 / stefan" |
195 ! |
195 ! |
196 |
196 |
197 lastMethodSourcesLock |
197 lastMethodSourcesLock |
198 LastMethodSourcesLock isNil ifTrue:[ |
198 LastMethodSourcesLock isNil ifTrue:[ |
199 self initialize |
199 self initialize |
200 ]. |
200 ]. |
201 ^ LastMethodSourcesLock |
201 ^ LastMethodSourcesLock |
202 ! ! |
202 ! ! |
203 |
203 |
204 !Method class methodsFor:'Signal constants'! |
204 !Method class methodsFor:'Signal constants'! |
226 "given a selector, return a prototype definition string" |
226 "given a selector, return a prototype definition string" |
227 |
227 |
228 |nA argNames| |
228 |nA argNames| |
229 |
229 |
230 (nA := aSelector numArgs) == 1 ifTrue:[ |
230 (nA := aSelector numArgs) == 1 ifTrue:[ |
231 argNames := #('arg') |
231 argNames := #('arg') |
232 ] ifFalse:[ |
232 ] ifFalse:[ |
233 argNames := (1 to:nA) collect:[:i | 'arg' , i printString]. |
233 argNames := (1 to:nA) collect:[:i | 'arg' , i printString]. |
234 ]. |
234 ]. |
235 ^ self |
235 ^ self |
236 methodDefinitionTemplateForSelector:aSelector |
236 methodDefinitionTemplateForSelector:aSelector |
237 andArgumentNames:argNames. |
237 andArgumentNames:argNames. |
238 |
238 |
239 " |
239 " |
240 Method methodDefinitionTemplateForSelector:#foo |
240 Method methodDefinitionTemplateForSelector:#foo |
241 Method methodDefinitionTemplateForSelector:#+ |
241 Method methodDefinitionTemplateForSelector:#+ |
242 Method methodDefinitionTemplateForSelector:#foo:bar:baz: |
242 Method methodDefinitionTemplateForSelector:#foo:bar:baz: |
245 |
245 |
246 methodDefinitionTemplateForSelector:aSelector andArgumentNames:argNames |
246 methodDefinitionTemplateForSelector:aSelector andArgumentNames:argNames |
247 "given a selector, return a prototype definition string" |
247 "given a selector, return a prototype definition string" |
248 |
248 |
249 aSelector numArgs > 0 ifTrue:[ |
249 aSelector numArgs > 0 ifTrue:[ |
250 aSelector isKeyword ifTrue:[ |
250 aSelector isKeyword ifTrue:[ |
251 ^ String streamContents:[:stream | |
251 ^ String streamContents:[:stream | |
252 aSelector keywords with:argNames do:[:eachKeyword :eachArgName| |
252 aSelector keywords with:argNames do:[:eachKeyword :eachArgName| |
253 stream nextPutAll:eachKeyword; nextPutAll:eachArgName; space. |
253 stream nextPutAll:eachKeyword; nextPutAll:eachArgName; space. |
254 ]. |
254 ]. |
255 stream backStep. "remove the last space" |
255 stream backStep. "remove the last space" |
256 ]. |
256 ]. |
257 ]. |
257 ]. |
258 ^ aSelector , ' ' , (argNames at:1) |
258 ^ aSelector , ' ' , (argNames at:1) |
259 ]. |
259 ]. |
260 ^ aSelector |
260 ^ aSelector |
261 |
261 |
262 " |
262 " |
263 Method methodDefinitionTemplateForSelector:#foo andArgumentNames:#() |
263 Method methodDefinitionTemplateForSelector:#foo andArgumentNames:#() |
287 |
287 |
288 !Method class methodsFor:'special'! |
288 !Method class methodsFor:'special'! |
289 |
289 |
290 flushSourceStreamCache |
290 flushSourceStreamCache |
291 LastFileLock critical:[ |
291 LastFileLock critical:[ |
292 LastSourceFileName := LastMethodSources := nil. |
292 LastSourceFileName := LastMethodSources := nil. |
293 LastFileReference at:1 put:0. |
293 LastFileReference at:1 put:0. |
294 ]. |
294 ]. |
295 |
295 |
296 " |
296 " |
297 Method flushSourceStreamCache |
297 Method flushSourceStreamCache |
298 " |
298 " |
321 |
321 |
322 annotateWith: annotation |
322 annotateWith: annotation |
323 |
323 |
324 | index | |
324 | index | |
325 index := self annotationIndexOf: annotation key. |
325 index := self annotationIndexOf: annotation key. |
326 index |
326 index |
327 ifNil: |
327 ifNil: |
328 [annotations := annotations |
328 [annotations := annotations |
329 ifNil:[Array with: annotation] |
329 ifNil:[Array with: annotation] |
330 ifNotNil:[annotations copyWith:annotation]] |
330 ifNotNil:[annotations copyWith:annotation]] |
331 ifNotNil: |
331 ifNotNil: |
332 [annotations at: index put: annotation]. |
332 [annotations at: index put: annotation]. |
333 "/ annotation annotatesMethod: self. |
333 "/ annotation annotatesMethod: self. |
334 |
334 |
335 " |
335 " |
336 (Object >> #yourself) annotateWith: (Annotation namespace: 'Fictious'). |
336 (Object >> #yourself) annotateWith: (Annotation namespace: 'Fictious'). |
337 (Object >> #yourself) annotations. |
337 (Object >> #yourself) annotations. |
338 (Object >> #yourself) annotationAt: #namespace: |
338 (Object >> #yourself) annotationAt: #namespace: |
339 " |
339 " |
340 |
340 |
341 "Created: / 19-05-2010 / 16:20:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
341 "Created: / 19-05-2010 / 16:20:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
342 "Modified: / 20-05-2010 / 11:22:55 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
342 "Modified: / 20-05-2010 / 11:22:55 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
343 ! |
343 ! |
345 annotationAt: key |
345 annotationAt: key |
346 |
346 |
347 | index | |
347 | index | |
348 |
348 |
349 index := self annotationIndexOf: key. |
349 index := self annotationIndexOf: key. |
350 index ifNil:[^nil]. |
350 index ifNil:[^nil]. |
351 ^self annotationAtIndex: index. |
351 ^self annotationAtIndex: index. |
352 |
352 |
353 " |
353 " |
354 (Object >> #yourself) annotationAt: #namespace: |
354 (Object >> #yourself) annotationAt: #namespace: |
355 " |
355 " |
356 |
356 |
357 "Created: / 19-05-2010 / 16:16:25 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
357 "Created: / 19-05-2010 / 16:16:25 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
358 "Modified: / 02-07-2010 / 22:35:56 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
358 "Modified: / 02-07-2010 / 22:35:56 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
359 ! |
359 ! |
360 |
360 |
361 annotations |
361 annotations |
362 "Returns annotations" |
362 "Returns annotations" |
363 |
363 |
364 annotations ifNil:[^#()]. |
364 annotations ifNil:[^#()]. |
365 "iterate over annotation array to |
365 "iterate over annotation array to |
366 trigger lazy-loading" |
366 trigger lazy-loading" |
367 self annotationsDo:[:ignored]. |
367 self annotationsDo:[:ignored]. |
368 ^ annotations |
368 ^ annotations |
369 |
369 |
370 "Modified: / 11-07-2010 / 19:25:27 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
370 "Modified: / 11-07-2010 / 19:25:27 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
383 ! |
383 ! |
384 |
384 |
385 annotationsAt: key |
385 annotationsAt: key |
386 |
386 |
387 ^OrderedCollection streamContents: |
387 ^OrderedCollection streamContents: |
388 [:annotStream| |
388 [:annotStream| |
389 self annotationsAt: key do: |
389 self annotationsAt: key do: |
390 [:annot|annotStream nextPut: annot]] |
390 [:annot|annotStream nextPut: annot]] |
391 |
391 |
392 "Created: / 16-07-2010 / 11:41:13 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
392 "Created: / 16-07-2010 / 11:41:13 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
393 ! |
393 ! |
394 |
394 |
395 annotationsAt: key do: block |
395 annotationsAt: key do: block |
396 |
396 |
397 | annots | |
397 | annots | |
398 annots := OrderedCollection new: 1. |
398 annots := OrderedCollection new: 1. |
399 self annotationsDo: |
399 self annotationsDo: |
400 [:annot| |
400 [:annot| |
401 annot key == key ifTrue: |
401 annot key == key ifTrue: |
402 [block value: annot]] |
402 [block value: annot]] |
403 |
403 |
404 "Created: / 16-07-2010 / 11:48:49 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
404 "Created: / 16-07-2010 / 11:48:49 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
405 ! |
405 ! |
406 |
406 |
407 annotationsAt: key1 orAt: key2 |
407 annotationsAt: key1 orAt: key2 |
408 |
408 |
409 ^OrderedCollection streamContents: |
409 ^OrderedCollection streamContents: |
410 [:annotStream| |
410 [:annotStream| |
411 self annotationsAt: key1 orAt: key2 do: |
411 self annotationsAt: key1 orAt: key2 do: |
412 [:annot|annotStream nextPut: annot]] |
412 [:annot|annotStream nextPut: annot]] |
413 |
413 |
414 "Created: / 16-07-2010 / 11:41:13 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
414 "Created: / 16-07-2010 / 11:41:13 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
415 ! |
415 ! |
416 |
416 |
417 annotationsAt: key1 orAt: key2 do: block |
417 annotationsAt: key1 orAt: key2 do: block |
418 |
418 |
419 | annots | |
419 | annots | |
420 annots := OrderedCollection new: 1. |
420 annots := OrderedCollection new: 1. |
421 self annotationsDo: |
421 self annotationsDo: |
422 [:annot| |
422 [:annot| |
423 (annot key == key1 or:[annot key == key2]) ifTrue: |
423 (annot key == key1 or:[annot key == key2]) ifTrue: |
424 [block value: annot]] |
424 [block value: annot]] |
425 |
425 |
426 "Created: / 16-07-2010 / 11:47:20 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
426 "Created: / 16-07-2010 / 11:47:20 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
427 ! |
427 ! |
428 |
428 |
429 annotationsDo: aBlock |
429 annotationsDo: aBlock |
430 |
430 |
431 annotations ifNil:[^nil]. |
431 annotations ifNil:[^nil]. |
432 1 to: annotations size do: |
432 1 to: annotations size do: |
433 [:i|aBlock value: (self annotationAtIndex: i)]. |
433 [:i|aBlock value: (self annotationAtIndex: i)]. |
434 |
434 |
435 "Created: / 02-07-2010 / 22:33:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
435 "Created: / 02-07-2010 / 22:33:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
436 "Modified: / 11-07-2010 / 19:38:54 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
436 "Modified: / 11-07-2010 / 19:38:54 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
437 ! |
437 ! |
438 |
438 |
446 "set the methods category" |
446 "set the methods category" |
447 |
447 |
448 |newCategory oldCategory cls| |
448 |newCategory oldCategory cls| |
449 |
449 |
450 aStringOrSymbol notNil ifTrue:[ |
450 aStringOrSymbol notNil ifTrue:[ |
451 newCategory := aStringOrSymbol. |
451 newCategory := aStringOrSymbol. |
452 newCategory ~= (oldCategory := category) ifTrue:[ |
452 newCategory ~= (oldCategory := category) ifTrue:[ |
453 self setCategory:newCategory. |
453 self setCategory:newCategory. |
454 |
454 |
455 cls := self mclass. |
455 cls := self mclass. |
456 cls notNil ifTrue:[ |
456 cls notNil ifTrue:[ |
457 cls addChangeRecordForMethodCategory:self category:newCategory. |
457 cls addChangeRecordForMethodCategory:self category:newCategory. |
458 self changed:#category with:oldCategory. "/ will vanish |
458 self changed:#category with:oldCategory. "/ will vanish |
459 cls changed:#organization with:self selector. "/ will vanish |
459 cls changed:#organization with:self selector. "/ will vanish |
460 Smalltalk changed:#methodCategory with:(Array with:cls with:self with:oldCategory). |
460 Smalltalk changed:#methodCategory with:(Array with:cls with:self with:oldCategory). |
461 ] |
461 ] |
462 ] |
462 ] |
463 ] |
463 ] |
464 |
464 |
465 "Modified: / 25-09-2007 / 16:15:24 / cg" |
465 "Modified: / 25-09-2007 / 16:15:24 / cg" |
466 ! |
466 ! |
467 |
467 |
476 src := self source. |
476 src := self source. |
477 src isNil ifTrue:[^ nil]. |
477 src isNil ifTrue:[^ nil]. |
478 ^ self programmingLanguage parserClass methodCommentFromSource:src |
478 ^ self programmingLanguage parserClass methodCommentFromSource:src |
479 |
479 |
480 " |
480 " |
481 (Method compiledMethodAt:#comment) comment |
481 (Method compiledMethodAt:#comment) comment |
482 (Object class compiledMethodAt:#infoPrinting:) comment |
482 (Object class compiledMethodAt:#infoPrinting:) comment |
483 " |
483 " |
484 |
484 |
485 "Modified: / 23-02-1998 / 10:26:08 / stefan" |
485 "Modified: / 23-02-1998 / 10:26:08 / stefan" |
486 "Modified: / 17-07-2010 / 14:23:56 / cg" |
486 "Modified: / 17-07-2010 / 14:23:56 / cg" |
539 by reading the source code file). |
539 by reading the source code file). |
540 This is required, when a methods package is changed, to assure that its |
540 This is required, when a methods package is changed, to assure that its |
541 sourceCode is not lost." |
541 sourceCode is not lost." |
542 |
542 |
543 source notNil ifTrue:[ |
543 source notNil ifTrue:[ |
544 sourcePosition notNil ifTrue:[ |
544 sourcePosition notNil ifTrue:[ |
545 "/ this looks wierd - but (self source) will retrieve the external source |
545 "/ this looks wierd - but (self source) will retrieve the external source |
546 "/ (from the file) and store it. So afterwards, we will have the string and |
546 "/ (from the file) and store it. So afterwards, we will have the string and |
547 "/ sourcePosition will be nil |
547 "/ sourcePosition will be nil |
548 self source:(self source) |
548 self source:(self source) |
549 ] |
549 ] |
550 ]. |
550 ]. |
551 ! |
551 ! |
552 |
552 |
553 mclass:aClass |
553 mclass:aClass |
554 "set the method's class" |
554 "set the method's class" |
569 is set, my programmming language is used as default namespace |
569 is set, my programmming language is used as default namespace |
570 (for compatibility reasons, for smalltalk methods nil is returned, |
570 (for compatibility reasons, for smalltalk methods nil is returned, |
571 which means that the method is not namespaced). |
571 which means that the method is not namespaced). |
572 " |
572 " |
573 |
573 |
574 | nsA lang | |
574 | nsA lang | |
575 nsA := self annotationAt: #namespace:. |
575 nsA := self annotationAt: #namespace:. |
576 nsA ifNotNil:[^nsA nameSpace]. |
576 nsA ifNotNil:[^nsA nameSpace]. |
577 |
577 |
578 ^(lang := self programmingLanguage) isSmalltalk |
578 ^(lang := self programmingLanguage) isSmalltalk |
579 ifTrue:[nil] |
579 ifTrue:[nil] |
580 ifFalse:[lang]. |
580 ifFalse:[lang]. |
581 |
581 |
582 " |
582 " |
583 (Method >> #nameSpace) nameSpace |
583 (Method >> #nameSpace) nameSpace |
584 (Object >> #yourself) nameSpace |
584 (Object >> #yourself) nameSpace |
585 |
585 |
586 " |
586 " |
587 |
587 |
588 "Created: / 26-04-2010 / 16:30:43 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
588 "Created: / 26-04-2010 / 16:30:43 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
589 "Modified: / 20-05-2010 / 09:38:09 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
589 "Modified: / 20-05-2010 / 09:38:09 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
590 ! |
590 ! |
599 |
599 |
600 nameSpaceName |
600 nameSpaceName |
601 |
601 |
602 | ns | |
602 | ns | |
603 ^(ns := self nameSpace) |
603 ^(ns := self nameSpace) |
604 ifNotNil:[ns name] |
604 ifNotNil:[ns name] |
605 ifNil:[''] |
605 ifNil:[''] |
606 ! |
606 ! |
607 |
607 |
608 originalMethodIfWrapped |
608 originalMethodIfWrapped |
609 "return the method the receiver is wrapping - none here" |
609 "return the method the receiver is wrapping - none here" |
610 |
610 |
617 |
617 |
618 "Answers overridden method or nil." |
618 "Answers overridden method or nil." |
619 |
619 |
620 Overrides ifNil:[^nil]. |
620 Overrides ifNil:[^nil]. |
621 ^(Overrides includesKey: self) |
621 ^(Overrides includesKey: self) |
622 ifTrue:[Overrides at: self] |
622 ifTrue:[Overrides at: self] |
623 |
623 |
624 "Created: / 17-06-2009 / 19:09:58 / Jan Vrany <vranyj1@fel.cvut.cz>" |
624 "Created: / 17-06-2009 / 19:09:58 / Jan Vrany <vranyj1@fel.cvut.cz>" |
625 ! |
625 ! |
626 |
626 |
627 overriddenMethod: aMethod |
627 overriddenMethod: aMethod |
641 |
641 |
642 |cls| |
642 |cls| |
643 |
643 |
644 package notNil ifTrue:[ ^ package ]. |
644 package notNil ifTrue:[ ^ package ]. |
645 (cls := self mclass) isNil ifTrue:[ |
645 (cls := self mclass) isNil ifTrue:[ |
646 ^ PackageId noProjectID. |
646 ^ PackageId noProjectID. |
647 ]. |
647 ]. |
648 "/ set it. |
648 "/ set it. |
649 package := cls getPackage. |
649 package := cls getPackage. |
650 package isNil ifTrue:[ |
650 package isNil ifTrue:[ |
651 ^ PackageId noProjectID. |
651 ^ PackageId noProjectID. |
652 ]. |
652 ]. |
653 ^ package |
653 ^ package |
654 |
654 |
655 "Modified: / 28-11-2006 / 12:12:43 / cg" |
655 "Modified: / 28-11-2006 / 12:12:43 / cg" |
656 ! |
656 ! |
659 "set the package-symbol" |
659 "set the package-symbol" |
660 |
660 |
661 |cls oldPackage newPackage| |
661 |cls oldPackage newPackage| |
662 |
662 |
663 aSymbol == PackageId noProjectID ifTrue:[ |
663 aSymbol == PackageId noProjectID ifTrue:[ |
664 newPackage := nil |
664 newPackage := nil |
665 ] ifFalse:[ |
665 ] ifFalse:[ |
666 newPackage := aSymbol |
666 newPackage := aSymbol |
667 ]. |
667 ]. |
668 |
668 |
669 package ~~ newPackage ifTrue:[ |
669 package ~~ newPackage ifTrue:[ |
670 oldPackage := package. |
670 oldPackage := package. |
671 "/ this is required, because otherwise I would no longer be able to |
671 "/ this is required, because otherwise I would no longer be able to |
672 "/ reconstruct my sourcecode (as the connection to the source-file is lost). |
672 "/ reconstruct my sourcecode (as the connection to the source-file is lost). |
673 self makeLocalStringSource. |
673 self makeLocalStringSource. |
674 package := newPackage. |
674 package := newPackage. |
675 |
675 |
676 cls := self mclass. |
676 cls := self mclass. |
677 |
677 |
678 self changed:#package. "/ will vanish |
678 self changed:#package. "/ will vanish |
679 cls changed:#methodPackage with:self selector. "/ will vanish |
679 cls changed:#methodPackage with:self selector. "/ will vanish |
680 |
680 |
681 Smalltalk changed:#projectOrganization with:(Array with:cls with:self with:oldPackage). |
681 Smalltalk changed:#projectOrganization with:(Array with:cls with:self with:oldPackage). |
682 cls addChangeRecordForMethodPackage:self package:newPackage. |
682 cls addChangeRecordForMethodPackage:self package:newPackage. |
683 ] |
683 ] |
684 |
684 |
685 "Modified: / 23-11-2006 / 17:01:02 / cg" |
685 "Modified: / 23-11-2006 / 17:01:02 / cg" |
686 ! |
686 ! |
687 |
687 |
695 |
695 |
696 setCategory:aStringOrSymbol |
696 setCategory:aStringOrSymbol |
697 "set the methods category (without change notification)" |
697 "set the methods category (without change notification)" |
698 |
698 |
699 aStringOrSymbol notNil ifTrue:[ |
699 aStringOrSymbol notNil ifTrue:[ |
700 category := aStringOrSymbol asSymbol |
700 category := aStringOrSymbol asSymbol |
701 ] |
701 ] |
702 |
702 |
703 "Modified: / 13.11.1998 / 23:55:05 / cg" |
703 "Modified: / 13.11.1998 / 23:55:05 / cg" |
704 ! |
704 ! |
705 |
705 |
721 " |
721 " |
722 sourcePosition isNil ifTrue:[^ source]. |
722 sourcePosition isNil ifTrue:[^ source]. |
723 source isNil ifTrue:[^ nil]. |
723 source isNil ifTrue:[^ nil]. |
724 |
724 |
725 self class lastMethodSourcesLock critical:[ |
725 self class lastMethodSourcesLock critical:[ |
726 LastMethodSources notNil ifTrue:[ |
726 LastMethodSources notNil ifTrue:[ |
727 chunk := LastMethodSources at:self ifAbsent:nil. |
727 chunk := LastMethodSources at:self ifAbsent:nil. |
728 ]. |
728 ]. |
729 ]. |
729 ]. |
730 chunk notNil ifTrue:[ |
730 chunk notNil ifTrue:[ |
731 ^ chunk |
731 ^ chunk |
732 ]. |
732 ]. |
733 |
733 |
734 LastFileLock |
734 LastFileLock |
735 critical:[ |
735 critical:[ |
736 "have to protect sourceStream from being closed as a side effect |
736 "have to protect sourceStream from being closed as a side effect |
737 of some other process fetching some the source from a different source file" |
737 of some other process fetching some the source from a different source file" |
738 |
738 |
739 sourceStream := self sourceStreamUsingCache:true. |
739 sourceStream := self sourceStreamUsingCache:true. |
740 sourceStream notNil ifTrue:[ |
740 sourceStream notNil ifTrue:[ |
741 [ |
741 [ |
742 chunk := self sourceChunkFromStream:sourceStream. |
742 chunk := self sourceChunkFromStream:sourceStream. |
743 ] on:DecodingError do:[:ex| |
743 ] on:DecodingError do:[:ex| |
744 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
744 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
745 |
745 |
746 ('DecodingError ignored when reading <1p> (<2p>)' expandMacrosWith:self whoString with:ex description) infoPrintCR. |
746 ('DecodingError ignored when reading <1p> (<2p>)' expandMacrosWith:self whoString with:ex description) infoPrintCR. |
747 sourceStream := self rawSourceStreamUsingCache:true. |
747 sourceStream := self rawSourceStreamUsingCache:true. |
748 ex restart. |
748 ex restart. |
749 ]. |
749 ]. |
750 ]. |
750 ]. |
751 ] |
751 ] |
752 timeoutMs:100 |
752 timeoutMs:100 |
753 ifBlocking:[ |
753 ifBlocking:[ |
754 "take care if LastFileLock is not available - maybe we are |
754 "take care if LastFileLock is not available - maybe we are |
755 called by a debugger while someone holds the lock. |
755 called by a debugger while someone holds the lock. |
756 Use uncached source streams" |
756 Use uncached source streams" |
757 sourceStream := self sourceStreamUsingCache:false. |
757 sourceStream := self sourceStreamUsingCache:false. |
758 sourceStream notNil ifTrue:[ |
758 sourceStream notNil ifTrue:[ |
759 [ |
759 [ |
760 chunk := self sourceChunkFromStream:sourceStream. |
760 chunk := self sourceChunkFromStream:sourceStream. |
761 sourceStream close. |
761 sourceStream close. |
762 ] on:DecodingError do:[:ex| |
762 ] on:DecodingError do:[:ex| |
763 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
763 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
764 ('DecodingError ignored when reading <1p> (<2p>)' expandMacrosWith:self whoString with:ex description) infoPrintCR. |
764 ('DecodingError ignored when reading <1p> (<2p>)' expandMacrosWith:self whoString with:ex description) infoPrintCR. |
765 sourceStream close. |
765 sourceStream close. |
766 sourceStream := self rawSourceStreamUsingCache:false. |
766 sourceStream := self rawSourceStreamUsingCache:false. |
767 ex restart. |
767 ex restart. |
768 ]. |
768 ]. |
769 ]. |
769 ]. |
770 ]. |
770 ]. |
771 |
771 |
772 "Cache the source of recently used methods" |
772 "Cache the source of recently used methods" |
773 chunk notNil ifTrue:[ |
773 chunk notNil ifTrue:[ |
774 UserPreferences current keepMethodSourceCode ifTrue:[ |
774 UserPreferences current keepMethodSourceCode ifTrue:[ |
775 source := chunk. |
775 source := chunk. |
776 sourcePosition := nil. |
776 sourcePosition := nil. |
777 ^ source. |
777 ^ source. |
778 ]. |
778 ]. |
779 |
779 |
780 CacheDictionary notNil ifTrue:[ |
780 CacheDictionary notNil ifTrue:[ |
781 self class lastMethodSourcesLock critical:[ |
781 self class lastMethodSourcesLock critical:[ |
782 LastMethodSources isNil ifTrue:[ |
782 LastMethodSources isNil ifTrue:[ |
783 LastMethodSources := CacheDictionary new:50. |
783 LastMethodSources := CacheDictionary new:50. |
784 ]. |
784 ]. |
785 LastMethodSources at:self put:chunk. |
785 LastMethodSources at:self put:chunk. |
786 ] |
786 ] |
787 ]. |
787 ]. |
788 ]. |
788 ]. |
789 |
789 |
790 ^ chunk |
790 ^ chunk |
791 |
791 |
792 "Modified: / 07-01-1997 / 16:20:09 / stefan" |
792 "Modified: / 07-01-1997 / 16:20:09 / stefan" |
920 %{ /* NOCONTEXT */ |
920 %{ /* NOCONTEXT */ |
921 #ifdef F_RESTRICTED |
921 #ifdef F_RESTRICTED |
922 INT f = __intVal(__INST(flags)); |
922 INT f = __intVal(__INST(flags)); |
923 |
923 |
924 if (f & F_RESTRICTED) { |
924 if (f & F_RESTRICTED) { |
925 RETURN (true); |
925 RETURN (true); |
926 } |
926 } |
927 #endif |
927 #endif |
928 %}. |
928 %}. |
929 ^ false |
929 ^ false |
930 ! ! |
930 ! ! |
951 #if defined(M_PRIVACY) |
951 #if defined(M_PRIVACY) |
952 INT f = __intVal(__INST(flags)); |
952 INT f = __intVal(__INST(flags)); |
953 INT p; |
953 INT p; |
954 |
954 |
955 if (aSymbol == @symbol(public)) |
955 if (aSymbol == @symbol(public)) |
956 p = 0; |
956 p = 0; |
957 else if (aSymbol == @symbol(protected)) |
957 else if (aSymbol == @symbol(protected)) |
958 p = F_PRIVATE; |
958 p = F_PRIVATE; |
959 else if (aSymbol == @symbol(private)) |
959 else if (aSymbol == @symbol(private)) |
960 p = F_CLASSPRIVATE; |
960 p = F_CLASSPRIVATE; |
961 else if (aSymbol == @symbol(ignored)) |
961 else if (aSymbol == @symbol(ignored)) |
962 p = F_IGNORED; |
962 p = F_IGNORED; |
963 else |
963 else |
964 RETURN(false); /* illegal symbol */ |
964 RETURN(false); /* illegal symbol */ |
965 |
965 |
966 |
966 |
967 f = (f & ~M_PRIVACY) | p; |
967 f = (f & ~M_PRIVACY) | p; |
968 __INST(flags) = __mkSmallInteger(f); |
968 __INST(flags) = __mkSmallInteger(f); |
969 #endif |
969 #endif |
997 INT f = __intVal(__INST(flags)); |
997 INT f = __intVal(__INST(flags)); |
998 switch (f & M_PRIVACY) { |
998 switch (f & M_PRIVACY) { |
999 |
999 |
1000 # ifdef F_PRIVATE |
1000 # ifdef F_PRIVATE |
1001 case F_PRIVATE: |
1001 case F_PRIVATE: |
1002 RETURN (@symbol(protected)); |
1002 RETURN (@symbol(protected)); |
1003 break; |
1003 break; |
1004 # endif |
1004 # endif |
1005 # ifdef F_CLASSPRIVATE |
1005 # ifdef F_CLASSPRIVATE |
1006 case F_CLASSPRIVATE: |
1006 case F_CLASSPRIVATE: |
1007 RETURN (@symbol(private)); |
1007 RETURN (@symbol(private)); |
1008 break; |
1008 break; |
1009 # endif |
1009 # endif |
1010 # ifdef F_IGNORED |
1010 # ifdef F_IGNORED |
1011 case F_IGNORED: |
1011 case F_IGNORED: |
1012 RETURN (@symbol(ignored)); |
1012 RETURN (@symbol(ignored)); |
1013 break; |
1013 break; |
1014 # endif |
1014 # endif |
1015 } |
1015 } |
1016 #endif |
1016 #endif |
1017 %}. |
1017 %}. |
1018 |
1018 |
1035 |oldPrivacy| |
1035 |oldPrivacy| |
1036 |
1036 |
1037 oldPrivacy := self privacy. |
1037 oldPrivacy := self privacy. |
1038 |
1038 |
1039 (self setPrivacy:aSymbol flushCaches:true) ifTrue:[ |
1039 (self setPrivacy:aSymbol flushCaches:true) ifTrue:[ |
1040 |myClass mySelector| |
1040 |myClass mySelector| |
1041 |
1041 |
1042 myClass := self mclass. |
1042 myClass := self mclass. |
1043 mySelector := self selector. |
1043 mySelector := self selector. |
1044 |
1044 |
1045 self changed:#privacy. "/ will vanish |
1045 self changed:#privacy. "/ will vanish |
1046 myClass notNil ifTrue:[ |
1046 myClass notNil ifTrue:[ |
1047 mySelector notNil ifTrue:[ |
1047 mySelector notNil ifTrue:[ |
1048 myClass changed:#methodPrivacy with:mySelector. "/ will vanish |
1048 myClass changed:#methodPrivacy with:mySelector. "/ will vanish |
1049 Smalltalk changed:#privacyOfMethod with:(Array with:myClass with:self with:oldPrivacy). |
1049 Smalltalk changed:#privacyOfMethod with:(Array with:myClass with:self with:oldPrivacy). |
1050 myClass addChangeRecordForMethodPrivacy:self. |
1050 myClass addChangeRecordForMethodPrivacy:self. |
1051 ] |
1051 ] |
1052 ] |
1052 ] |
1053 ] |
1053 ] |
1054 |
1054 |
1055 "Modified: / 23-11-2006 / 17:03:20 / cg" |
1055 "Modified: / 23-11-2006 / 17:03:20 / cg" |
1056 ! |
1056 ! |
1057 |
1057 |
1074 INT f = __intVal(__INST(flags)); |
1074 INT f = __intVal(__INST(flags)); |
1075 INT old; |
1075 INT old; |
1076 |
1076 |
1077 old = f; |
1077 old = f; |
1078 if (aBoolean == true) |
1078 if (aBoolean == true) |
1079 f |= F_RESTRICTED; |
1079 f |= F_RESTRICTED; |
1080 else |
1080 else |
1081 f &= ~F_RESTRICTED; |
1081 f &= ~F_RESTRICTED; |
1082 __INST(flags) = __mkSmallInteger(f); |
1082 __INST(flags) = __mkSmallInteger(f); |
1083 if (old & F_RESTRICTED) |
1083 if (old & F_RESTRICTED) |
1084 RETURN(true); |
1084 RETURN(true); |
1085 #endif |
1085 #endif |
1086 %}. |
1086 %}. |
1087 ^ false |
1087 ^ false |
1088 |
1088 |
1089 " |
1089 " |
1134 |
1134 |
1135 "/ |
1135 "/ |
1136 "/ no need to flush, if changing from private to public |
1136 "/ no need to flush, if changing from private to public |
1137 "/ |
1137 "/ |
1138 doFlush ifTrue:[ |
1138 doFlush ifTrue:[ |
1139 (aSymbol == #public and:[old ~~ #ignored]) ifFalse:[ |
1139 (aSymbol == #public and:[old ~~ #ignored]) ifFalse:[ |
1140 (sel := self selector) notNil ifTrue:[ |
1140 (sel := self selector) notNil ifTrue:[ |
1141 ObjectMemory flushCachesForSelector:sel |
1141 ObjectMemory flushCachesForSelector:sel |
1142 ] ifFalse:[ |
1142 ] ifFalse:[ |
1143 ObjectMemory flushCaches. |
1143 ObjectMemory flushCaches. |
1144 ]. |
1144 ]. |
1145 ]. |
1145 ]. |
1146 ]. |
1146 ]. |
1147 ^ true |
1147 ^ true |
1148 ! ! |
1148 ! ! |
1149 |
1149 |
1150 !Method methodsFor:'binary storage'! |
1150 !Method methodsFor:'binary storage'! |
1161 or to compile lazy methods down to executable ones." |
1161 or to compile lazy methods down to executable ones." |
1162 |
1162 |
1163 |mthd| |
1163 |mthd| |
1164 |
1164 |
1165 byteCode notNil ifTrue:[ |
1165 byteCode notNil ifTrue:[ |
1166 " |
1166 " |
1167 is already a bytecoded method |
1167 is already a bytecoded method |
1168 " |
1168 " |
1169 ^ self |
1169 ^ self |
1170 ]. |
1170 ]. |
1171 |
1171 |
1172 ParserFlags |
1172 ParserFlags |
1173 withSTCCompilation:#never |
1173 withSTCCompilation:#never |
1174 do:[ |
1174 do:[ |
1175 mthd := self asExecutableMethod. |
1175 mthd := self asExecutableMethod. |
1176 ]. |
1176 ]. |
1177 ^ mthd |
1177 ^ mthd |
1178 |
1178 |
1179 "Created: 24.10.1995 / 14:02:32 / cg" |
1179 "Created: 24.10.1995 / 14:02:32 / cg" |
1180 "Modified: 5.1.1997 / 01:01:53 / cg" |
1180 "Modified: 5.1.1997 / 01:01:53 / cg" |
1181 ! |
1181 ! |
1182 |
1182 |
1183 asByteCodeMethodWithSource:newSource |
1183 asByteCodeMethodWithSource:newSource |
1184 |mthd| |
1184 |mthd| |
1185 |
1185 |
1186 ParserFlags |
1186 ParserFlags |
1187 withSTCCompilation:#never |
1187 withSTCCompilation:#never |
1188 do:[ |
1188 do:[ |
1189 mthd := self asExecutableMethodWithSource:newSource. |
1189 mthd := self asExecutableMethodWithSource:newSource. |
1190 ]. |
1190 ]. |
1191 ^ mthd |
1191 ^ mthd |
1192 |
1192 |
1193 "Created: 24.10.1995 / 14:02:32 / cg" |
1193 "Created: 24.10.1995 / 14:02:32 / cg" |
1194 "Modified: 5.1.1997 / 01:01:53 / cg" |
1194 "Modified: 5.1.1997 / 01:01:53 / cg" |
1195 ! |
1195 ! |
1204 Can be used to compile lazy methods down to executable ones." |
1204 Can be used to compile lazy methods down to executable ones." |
1205 |
1205 |
1206 |temporaryMethod sourceString| |
1206 |temporaryMethod sourceString| |
1207 |
1207 |
1208 byteCode notNil ifTrue:[ |
1208 byteCode notNil ifTrue:[ |
1209 " |
1209 " |
1210 is already a bytecoded method |
1210 is already a bytecoded method |
1211 " |
1211 " |
1212 ^ self |
1212 ^ self |
1213 ]. |
1213 ]. |
1214 |
1214 |
1215 sourceString := self source. |
1215 sourceString := self source. |
1216 sourceString isNil ifTrue:[ |
1216 sourceString isNil ifTrue:[ |
1217 'Method [warning]: cannot generate bytecode (no source for compilation)' errorPrintCR. |
1217 'Method [warning]: cannot generate bytecode (no source for compilation)' errorPrintCR. |
1218 ^ nil |
1218 ^ nil |
1219 ]. |
1219 ]. |
1220 |
1220 |
1221 temporaryMethod := self asExecutableMethodWithSource:sourceString. |
1221 temporaryMethod := self asExecutableMethodWithSource:sourceString. |
1222 |
1222 |
1223 (temporaryMethod isNil or:[temporaryMethod == #Error]) ifTrue:[ |
1223 (temporaryMethod isNil or:[temporaryMethod == #Error]) ifTrue:[ |
1224 'Method [warning]: cannot generate bytecode (contains primitive code or error)' errorPrintCR. |
1224 'Method [warning]: cannot generate bytecode (contains primitive code or error)' errorPrintCR. |
1225 ^ nil. |
1225 ^ nil. |
1226 ]. |
1226 ]. |
1227 "/ |
1227 "/ |
1228 "/ try to save a bit of memory, by sharing the source (whatever it is) |
1228 "/ try to save a bit of memory, by sharing the source (whatever it is) |
1229 "/ |
1229 "/ |
1230 temporaryMethod sourceFilename:source position:sourcePosition. |
1230 temporaryMethod sourceFilename:source position:sourcePosition. |
1234 asExecutableMethodWithSource:newSource |
1234 asExecutableMethodWithSource:newSource |
1235 |temporaryMethod cls| |
1235 |temporaryMethod cls| |
1236 |
1236 |
1237 cls := self containingClass. |
1237 cls := self containingClass. |
1238 cls isNil ifTrue:[ |
1238 cls isNil ifTrue:[ |
1239 'Method [warning]: cannot generate bytecode (no class for compilation)' errorPrintCR. |
1239 'Method [warning]: cannot generate bytecode (no class for compilation)' errorPrintCR. |
1240 ^ nil |
1240 ^ nil |
1241 ]. |
1241 ]. |
1242 |
1242 |
1243 "we have to sequentialize this using a lock-semaphore, |
1243 "we have to sequentialize this using a lock-semaphore, |
1244 to make sure only one method is compiled at a time. |
1244 to make sure only one method is compiled at a time. |
1245 Otherwise, we might get into trouble, if (due to a timeout) |
1245 Otherwise, we might get into trouble, if (due to a timeout) |
1246 another recompile is forced while compiling this one ... |
1246 another recompile is forced while compiling this one ... |
1247 (happened when autoloading animation demos) |
1247 (happened when autoloading animation demos) |
1248 " |
1248 " |
1249 CompilationLock critical:[ |
1249 CompilationLock critical:[ |
1250 " |
1250 " |
1251 dont want this to go into the changes file, |
1251 dont want this to go into the changes file, |
1252 dont want output on Transcript and definitely |
1252 dont want output on Transcript and definitely |
1253 dont want a lazy method ... |
1253 dont want a lazy method ... |
1254 " |
1254 " |
1255 Class withoutUpdatingChangesDo:[ |
1255 Class withoutUpdatingChangesDo:[ |
1256 |silent lazy| |
1256 |silent lazy| |
1257 |
1257 |
1258 silent := Smalltalk silentLoading:true. |
1258 silent := Smalltalk silentLoading:true. |
1259 lazy := Compiler compileLazy:false. |
1259 lazy := Compiler compileLazy:false. |
1260 |
1260 |
1261 [ |
1261 [ |
1262 |compiler| |
1262 |compiler| |
1263 |
1263 |
1264 Class nameSpaceQuerySignal answer:(cls nameSpace) |
1264 Class nameSpaceQuerySignal answer:(cls nameSpace) |
1265 do:[ |
1265 do:[ |
1266 compiler := cls compilerClass. |
1266 compiler := cls compilerClass. |
1267 |
1267 |
1268 "/ |
1268 "/ |
1269 "/ kludge - have to make ST/X's compiler protocol |
1269 "/ kludge - have to make ST/X's compiler protocol |
1270 "/ be compatible to ST-80's |
1270 "/ be compatible to ST-80's |
1271 "/ |
1271 "/ |
1272 (compiler respondsTo:#compile:forClass:inCategory:notifying:install:) |
1272 (compiler respondsTo:#compile:forClass:inCategory:notifying:install:) |
1273 ifTrue:[ |
1273 ifTrue:[ |
1274 temporaryMethod := compiler |
1274 temporaryMethod := compiler |
1275 compile:newSource |
1275 compile:newSource |
1276 forClass:cls |
1276 forClass:cls |
1277 inCategory:(self category) |
1277 inCategory:(self category) |
1278 notifying:nil |
1278 notifying:nil |
1279 install:false. |
1279 install:false. |
1280 ] ifFalse:[ |
1280 ] ifFalse:[ |
1281 temporaryMethod := compiler new |
1281 temporaryMethod := compiler new |
1282 compile:newSource |
1282 compile:newSource |
1283 in:cls |
1283 in:cls |
1284 notifying:nil |
1284 notifying:nil |
1285 ifFail:nil |
1285 ifFail:nil |
1286 ]. |
1286 ]. |
1287 ]. |
1287 ]. |
1288 ] ensure:[ |
1288 ] ensure:[ |
1289 Compiler compileLazy:lazy. |
1289 Compiler compileLazy:lazy. |
1290 Smalltalk silentLoading:silent. |
1290 Smalltalk silentLoading:silent. |
1291 ] |
1291 ] |
1292 ]. |
1292 ]. |
1293 ]. |
1293 ]. |
1294 (temporaryMethod isNil or:[temporaryMethod == #Error]) ifTrue:[ |
1294 (temporaryMethod isNil or:[temporaryMethod == #Error]) ifTrue:[ |
1295 'Method [warning]: cannot generate bytecode (contains primitive code or error)' errorPrintCR. |
1295 'Method [warning]: cannot generate bytecode (contains primitive code or error)' errorPrintCR. |
1296 ^ nil. |
1296 ^ nil. |
1297 ]. |
1297 ]. |
1298 "/ |
1298 "/ |
1299 "/ try to save a bit of memory, by sharing the source (whatever it is) |
1299 "/ try to save a bit of memory, by sharing the source (whatever it is) |
1300 "/ |
1300 "/ |
1301 temporaryMethod source:newSource. |
1301 temporaryMethod source:newSource. |
1314 |
1314 |
1315 |aCopy| |
1315 |aCopy| |
1316 |
1316 |
1317 aCopy := super copy. |
1317 aCopy := super copy. |
1318 sourcePosition notNil ifTrue:[ |
1318 sourcePosition notNil ifTrue:[ |
1319 aCopy source:(self source) |
1319 aCopy source:(self source) |
1320 ]. |
1320 ]. |
1321 aCopy mclass:nil. |
1321 aCopy mclass:nil. |
1322 ^ aCopy |
1322 ^ aCopy |
1323 |
1323 |
1324 "Modified: 16.1.1997 / 01:27:25 / cg" |
1324 "Modified: 16.1.1997 / 01:27:25 / cg" |
1347 * for reasons too far from being explained here, |
1347 * for reasons too far from being explained here, |
1348 * this MUST be a compiled method |
1348 * this MUST be a compiled method |
1349 */ |
1349 */ |
1350 %}. |
1350 %}. |
1351 ^ InvalidCodeError |
1351 ^ InvalidCodeError |
1352 raiseErrorString:'invalid method - not executable'. |
1352 raiseErrorString:'invalid method - not executable'. |
1353 |
1353 |
1354 "Modified: 4.11.1996 / 22:45:06 / cg" |
1354 "Modified: 4.11.1996 / 22:45:06 / cg" |
1355 ! |
1355 ! |
1356 |
1356 |
1357 invalidCodeObjectWith:arg |
1357 invalidCodeObjectWith:arg |
1366 * for reasons too far from being explained here, |
1366 * for reasons too far from being explained here, |
1367 * this MUST be a compiled method |
1367 * this MUST be a compiled method |
1368 */ |
1368 */ |
1369 %}. |
1369 %}. |
1370 ^ InvalidCodeError |
1370 ^ InvalidCodeError |
1371 raiseErrorString:'invalid method - not executable'. |
1371 raiseErrorString:'invalid method - not executable'. |
1372 |
1372 |
1373 "Created: 4.11.1996 / 21:16:16 / cg" |
1373 "Created: 4.11.1996 / 21:16:16 / cg" |
1374 "Modified: 4.11.1996 / 22:45:12 / cg" |
1374 "Modified: 4.11.1996 / 22:45:12 / cg" |
1375 ! |
1375 ! |
1376 |
1376 |
1386 * for reasons too far from being explained here, |
1386 * for reasons too far from being explained here, |
1387 * this MUST be a compiled method |
1387 * this MUST be a compiled method |
1388 */ |
1388 */ |
1389 %}. |
1389 %}. |
1390 ^ InvalidCodeError |
1390 ^ InvalidCodeError |
1391 raiseErrorString:'invalid method - not executable'. |
1391 raiseErrorString:'invalid method - not executable'. |
1392 |
1392 |
1393 "Created: 4.11.1996 / 21:16:41 / cg" |
1393 "Created: 4.11.1996 / 21:16:41 / cg" |
1394 "Modified: 4.11.1996 / 22:45:15 / cg" |
1394 "Modified: 4.11.1996 / 22:45:15 / cg" |
1395 ! |
1395 ! |
1396 |
1396 |
1406 * for reasons too far from being explained here, |
1406 * for reasons too far from being explained here, |
1407 * this MUST be a compiled method |
1407 * this MUST be a compiled method |
1408 */ |
1408 */ |
1409 %}. |
1409 %}. |
1410 ^ InvalidCodeError |
1410 ^ InvalidCodeError |
1411 raiseErrorString:'invalid method - not executable'. |
1411 raiseErrorString:'invalid method - not executable'. |
1412 |
1412 |
1413 "Created: 4.11.1996 / 21:16:51 / cg" |
1413 "Created: 4.11.1996 / 21:16:51 / cg" |
1414 "Modified: 4.11.1996 / 22:45:18 / cg" |
1414 "Modified: 4.11.1996 / 22:45:18 / cg" |
1415 ! |
1415 ! |
1416 |
1416 |
1426 * for reasons too far from being explained here, |
1426 * for reasons too far from being explained here, |
1427 * this MUST be a compiled method |
1427 * this MUST be a compiled method |
1428 */ |
1428 */ |
1429 %}. |
1429 %}. |
1430 ^ InvalidCodeError |
1430 ^ InvalidCodeError |
1431 raiseErrorString:'invalid method - not executable'. |
1431 raiseErrorString:'invalid method - not executable'. |
1432 |
1432 |
1433 "Created: 4.11.1996 / 21:17:00 / cg" |
1433 "Created: 4.11.1996 / 21:17:00 / cg" |
1434 "Modified: 4.11.1996 / 22:45:22 / cg" |
1434 "Modified: 4.11.1996 / 22:45:22 / cg" |
1435 ! |
1435 ! |
1436 |
1436 |
1446 * for reasons too far from being explained here, |
1446 * for reasons too far from being explained here, |
1447 * this MUST be a compiled method |
1447 * this MUST be a compiled method |
1448 */ |
1448 */ |
1449 %}. |
1449 %}. |
1450 ^ InvalidCodeError |
1450 ^ InvalidCodeError |
1451 raiseErrorString:'invalid method - not executable'. |
1451 raiseErrorString:'invalid method - not executable'. |
1452 |
1452 |
1453 "Created: 4.11.1996 / 21:17:09 / cg" |
1453 "Created: 4.11.1996 / 21:17:09 / cg" |
1454 "Modified: 4.11.1996 / 22:45:25 / cg" |
1454 "Modified: 4.11.1996 / 22:45:25 / cg" |
1455 ! |
1455 ! |
1456 |
1456 |
1466 * for reasons too far from being explained here, |
1466 * for reasons too far from being explained here, |
1467 * this MUST be a compiled method |
1467 * this MUST be a compiled method |
1468 */ |
1468 */ |
1469 %}. |
1469 %}. |
1470 ^ InvalidCodeError |
1470 ^ InvalidCodeError |
1471 raiseErrorString:'invalid method - not executable'. |
1471 raiseErrorString:'invalid method - not executable'. |
1472 |
1472 |
1473 "Created: 4.11.1996 / 21:17:17 / cg" |
1473 "Created: 4.11.1996 / 21:17:17 / cg" |
1474 "Modified: 4.11.1996 / 22:45:28 / cg" |
1474 "Modified: 4.11.1996 / 22:45:28 / cg" |
1475 ! |
1475 ! |
1476 |
1476 |
1486 * for reasons too far from being explained here, |
1486 * for reasons too far from being explained here, |
1487 * this MUST be a compiled method |
1487 * this MUST be a compiled method |
1488 */ |
1488 */ |
1489 %}. |
1489 %}. |
1490 ^ InvalidCodeError |
1490 ^ InvalidCodeError |
1491 raiseErrorString:'invalid method - not executable'. |
1491 raiseErrorString:'invalid method - not executable'. |
1492 |
1492 |
1493 "Created: 4.11.1996 / 21:17:25 / cg" |
1493 "Created: 4.11.1996 / 21:17:25 / cg" |
1494 "Modified: 4.11.1996 / 22:45:31 / cg" |
1494 "Modified: 4.11.1996 / 22:45:31 / cg" |
1495 ! |
1495 ! |
1496 |
1496 |
1506 * for reasons too far from being explained here, |
1506 * for reasons too far from being explained here, |
1507 * this MUST be a compiled method |
1507 * this MUST be a compiled method |
1508 */ |
1508 */ |
1509 %}. |
1509 %}. |
1510 ^ InvalidCodeError |
1510 ^ InvalidCodeError |
1511 raiseErrorString:'invalid method - not executable'. |
1511 raiseErrorString:'invalid method - not executable'. |
1512 |
1512 |
1513 "Created: 4.11.1996 / 21:17:32 / cg" |
1513 "Created: 4.11.1996 / 21:17:32 / cg" |
1514 "Modified: 4.11.1996 / 22:45:38 / cg" |
1514 "Modified: 4.11.1996 / 22:45:38 / cg" |
1515 ! |
1515 ! |
1516 |
1516 |
1526 * for reasons too far from being explained here, |
1526 * for reasons too far from being explained here, |
1527 * this MUST be a compiled method |
1527 * this MUST be a compiled method |
1528 */ |
1528 */ |
1529 %}. |
1529 %}. |
1530 ^ InvalidCodeError |
1530 ^ InvalidCodeError |
1531 raiseErrorString:'invalid method - not executable'. |
1531 raiseErrorString:'invalid method - not executable'. |
1532 |
1532 |
1533 "Created: 4.11.1996 / 21:17:37 / cg" |
1533 "Created: 4.11.1996 / 21:17:37 / cg" |
1534 "Modified: 4.11.1996 / 22:45:41 / cg" |
1534 "Modified: 4.11.1996 / 22:45:41 / cg" |
1535 ! |
1535 ! |
1536 |
1536 |
1546 * for reasons too far from being explained here, |
1546 * for reasons too far from being explained here, |
1547 * this MUST be a compiled method |
1547 * this MUST be a compiled method |
1548 */ |
1548 */ |
1549 %}. |
1549 %}. |
1550 ^ InvalidCodeError |
1550 ^ InvalidCodeError |
1551 raiseErrorString:'invalid method - not executable'. |
1551 raiseErrorString:'invalid method - not executable'. |
1552 |
1552 |
1553 "Created: 4.11.1996 / 21:17:45 / cg" |
1553 "Created: 4.11.1996 / 21:17:45 / cg" |
1554 "Modified: 4.11.1996 / 22:45:44 / cg" |
1554 "Modified: 4.11.1996 / 22:45:44 / cg" |
1555 ! |
1555 ! |
1556 |
1556 |
1566 * for reasons too far from being explained here, |
1566 * for reasons too far from being explained here, |
1567 * this MUST be a compiled method |
1567 * this MUST be a compiled method |
1568 */ |
1568 */ |
1569 %}. |
1569 %}. |
1570 ^ InvalidCodeError |
1570 ^ InvalidCodeError |
1571 raiseErrorString:'invalid method - not executable'. |
1571 raiseErrorString:'invalid method - not executable'. |
1572 |
1572 |
1573 "Created: 4.11.1996 / 21:17:52 / cg" |
1573 "Created: 4.11.1996 / 21:17:52 / cg" |
1574 "Modified: 4.11.1996 / 22:45:47 / cg" |
1574 "Modified: 4.11.1996 / 22:45:47 / cg" |
1575 ! |
1575 ! |
1576 |
1576 |
1586 * for reasons too far from being explained here, |
1586 * for reasons too far from being explained here, |
1587 * this MUST be a compiled method |
1587 * this MUST be a compiled method |
1588 */ |
1588 */ |
1589 %}. |
1589 %}. |
1590 ^ InvalidCodeError |
1590 ^ InvalidCodeError |
1591 raiseErrorString:'invalid method - not executable'. |
1591 raiseErrorString:'invalid method - not executable'. |
1592 |
1592 |
1593 "Created: 4.11.1996 / 20:51:28 / cg" |
1593 "Created: 4.11.1996 / 20:51:28 / cg" |
1594 "Modified: 4.11.1996 / 22:46:01 / cg" |
1594 "Modified: 4.11.1996 / 22:46:01 / cg" |
1595 ! |
1595 ! |
1596 |
1596 |
1606 * for reasons too far from being explained here, |
1606 * for reasons too far from being explained here, |
1607 * this MUST be a compiled method |
1607 * this MUST be a compiled method |
1608 */ |
1608 */ |
1609 %}. |
1609 %}. |
1610 ^ InvalidCodeError |
1610 ^ InvalidCodeError |
1611 raiseErrorString:'invalid method - not executable'. |
1611 raiseErrorString:'invalid method - not executable'. |
1612 |
1612 |
1613 "Created: 4.11.1996 / 21:18:09 / cg" |
1613 "Created: 4.11.1996 / 21:18:09 / cg" |
1614 "Modified: 4.11.1996 / 22:45:57 / cg" |
1614 "Modified: 4.11.1996 / 22:45:57 / cg" |
1615 ! |
1615 ! |
1616 |
1616 |
1626 * for reasons too far from being explained here, |
1626 * for reasons too far from being explained here, |
1627 * this MUST be a compiled method |
1627 * this MUST be a compiled method |
1628 */ |
1628 */ |
1629 %}. |
1629 %}. |
1630 ^ InvalidCodeError |
1630 ^ InvalidCodeError |
1631 raiseErrorString:'invalid method - not executable'. |
1631 raiseErrorString:'invalid method - not executable'. |
1632 |
1632 |
1633 "Created: 4.11.1996 / 21:18:17 / cg" |
1633 "Created: 4.11.1996 / 21:18:17 / cg" |
1634 "Modified: 4.11.1996 / 22:45:55 / cg" |
1634 "Modified: 4.11.1996 / 22:45:55 / cg" |
1635 ! |
1635 ! |
1636 |
1636 |
1646 * for reasons too far from being explained here, |
1646 * for reasons too far from being explained here, |
1647 * this MUST be a compiled method |
1647 * this MUST be a compiled method |
1648 */ |
1648 */ |
1649 %}. |
1649 %}. |
1650 ^ InvalidCodeError |
1650 ^ InvalidCodeError |
1651 raiseErrorString:'invalid method - not executable'. |
1651 raiseErrorString:'invalid method - not executable'. |
1652 |
1652 |
1653 "Created: 4.11.1996 / 21:18:22 / cg" |
1653 "Created: 4.11.1996 / 21:18:22 / cg" |
1654 "Modified: 4.11.1996 / 22:45:52 / cg" |
1654 "Modified: 4.11.1996 / 22:45:52 / cg" |
1655 ! |
1655 ! |
1656 |
1656 |
1695 * for reasons too far from being explained here, |
1695 * for reasons too far from being explained here, |
1696 * this MUST be a compiled method |
1696 * this MUST be a compiled method |
1697 */ |
1697 */ |
1698 %}. |
1698 %}. |
1699 ^ InvalidCodeError |
1699 ^ InvalidCodeError |
1700 raiseRequestWith:self |
1700 raiseRequestWith:self |
1701 errorString:'invalid method - not compiled'. |
1701 errorString:'invalid method - not compiled'. |
1702 |
1702 |
1703 "Modified: 4.11.1996 / 22:58:02 / cg" |
1703 "Modified: 4.11.1996 / 22:58:02 / cg" |
1704 ! |
1704 ! |
1705 |
1705 |
1706 unloadedCodeObject |
1706 unloadedCodeObject |
1715 * for reasons too far from being explained here, |
1715 * for reasons too far from being explained here, |
1716 * this MUST be a compiled method |
1716 * this MUST be a compiled method |
1717 */ |
1717 */ |
1718 %}. |
1718 %}. |
1719 ^ InvalidCodeError |
1719 ^ InvalidCodeError |
1720 raiseRequestWith:self |
1720 raiseRequestWith:self |
1721 errorString:'invalid method - unloaded'. |
1721 errorString:'invalid method - unloaded'. |
1722 |
1722 |
1723 "Created: 4.11.1996 / 22:57:54 / cg" |
1723 "Created: 4.11.1996 / 22:57:54 / cg" |
1724 "Modified: 4.11.1996 / 22:58:28 / cg" |
1724 "Modified: 4.11.1996 / 22:58:28 / cg" |
1725 ! ! |
1725 ! ! |
1726 |
1726 |
1739 self basicPrintOn:aStream."/ aStream nextPutAll:(self classNameWithArticle). |
1739 self basicPrintOn:aStream."/ aStream nextPutAll:(self classNameWithArticle). |
1740 aStream nextPut:$(. |
1740 aStream nextPut:$(. |
1741 |
1741 |
1742 classAndSelector := self who. |
1742 classAndSelector := self who. |
1743 classAndSelector isNil ifTrue:[ |
1743 classAndSelector isNil ifTrue:[ |
1744 " |
1744 " |
1745 not anchored in any class. |
1745 not anchored in any class. |
1746 check if wrapped (to be more informative in inspectors) |
1746 check if wrapped (to be more informative in inspectors) |
1747 " |
1747 " |
1748 m := self wrapper. |
1748 m := self wrapper. |
1749 m notNil ifTrue:[ |
1749 m notNil ifTrue:[ |
1750 classAndSelector := m who. |
1750 classAndSelector := m who. |
1751 wrapped := true. |
1751 wrapped := true. |
1752 ] |
1752 ] |
1753 ]. |
1753 ]. |
1754 classAndSelector notNil ifTrue:[ |
1754 classAndSelector notNil ifTrue:[ |
1755 (classAndSelector methodClass) name printOn:aStream. |
1755 (classAndSelector methodClass) name printOn:aStream. |
1756 aStream nextPutAll:' '. |
1756 aStream nextPutAll:' '. |
1757 (classAndSelector methodSelector) printOn:aStream. |
1757 (classAndSelector methodSelector) printOn:aStream. |
1758 ] ifFalse:[ |
1758 ] ifFalse:[ |
1759 " |
1759 " |
1760 sorry, a method which is nowhere anchored |
1760 sorry, a method which is nowhere anchored |
1761 " |
1761 " |
1762 aStream nextPutAll:'unbound' |
1762 aStream nextPutAll:'unbound' |
1763 ]. |
1763 ]. |
1764 aStream nextPut:$). |
1764 aStream nextPut:$). |
1765 |
1765 |
1766 wrapped ifTrue:[ |
1766 wrapped ifTrue:[ |
1767 aStream nextPutAll:'; wrapped' |
1767 aStream nextPutAll:'; wrapped' |
1768 ]. |
1768 ]. |
1769 |
1769 |
1770 " |
1770 " |
1771 (Object compiledMethodAt:#at:) printOn:Transcript. Transcript cr. |
1771 (Object compiledMethodAt:#at:) printOn:Transcript. Transcript cr. |
1772 (Object compiledMethodAt:#at:) copy printOn:Transcript. Transcript cr. |
1772 (Object compiledMethodAt:#at:) copy printOn:Transcript. Transcript cr. |
1784 |
1784 |
1785 |who| |
1785 |who| |
1786 |
1786 |
1787 who := self who. |
1787 who := self who. |
1788 who notNil ifTrue:[ |
1788 who notNil ifTrue:[ |
1789 ^ who methodClass name , ' >> ' , (who methodSelector storeString) |
1789 ^ who methodClass name , ' >> ' , (who methodSelector storeString) |
1790 ]. |
1790 ]. |
1791 ^ 'unboundMethod' |
1791 ^ 'unboundMethod' |
1792 |
1792 |
1793 " |
1793 " |
1794 Method new whoString |
1794 Method new whoString |
1807 initialized" |
1807 initialized" |
1808 |
1808 |
1809 | annotation args | |
1809 | annotation args | |
1810 annotations ifNil:[^nil]. |
1810 annotations ifNil:[^nil]. |
1811 annotation := annotations at: index. |
1811 annotation := annotations at: index. |
1812 annotation isArray ifTrue:[ |
1812 annotation isArray ifTrue:[ |
1813 args := annotation size == 2 |
1813 args := annotation size == 2 |
1814 ifTrue:[annotation second] |
1814 ifTrue:[annotation second] |
1815 ifFalse:[#()]. |
1815 ifFalse:[#()]. |
1816 args isArray ifFalse:[args := Array with: args]. |
1816 args isArray ifFalse:[args := Array with: args]. |
1817 annotation := Annotation |
1817 annotation := Annotation |
1818 key: annotation first |
1818 key: annotation first |
1819 arguments: args. |
1819 arguments: args. |
1820 annotation isUnknown ifFalse:[ |
1820 annotation isUnknown ifFalse:[ |
1821 annotations at: index put: annotation. |
1821 annotations at: index put: annotation. |
1822 "/ annotation annotatesMethod: self |
1822 "/ annotation annotatesMethod: self |
1823 ]. |
1823 ]. |
1824 ]. |
1824 ]. |
1825 ^annotation |
1825 ^annotation |
1826 |
1826 |
1827 "Created: / 02-07-2010 / 22:30:44 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1827 "Created: / 02-07-2010 / 22:30:44 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1828 "Modified: / 11-07-2010 / 19:39:33 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1828 "Modified: / 11-07-2010 / 19:39:33 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1832 |
1832 |
1833 "Returns index of annotation with given key |
1833 "Returns index of annotation with given key |
1834 or nil if there is no such annotation" |
1834 or nil if there is no such annotation" |
1835 |
1835 |
1836 annotations ifNil:[^nil]. |
1836 annotations ifNil:[^nil]. |
1837 |
1837 |
1838 annotations keysAndValuesDo: |
1838 annotations keysAndValuesDo: |
1839 [:index :annotationOrArray| |
1839 [:index :annotationOrArray| |
1840 annotationOrArray isArray |
1840 annotationOrArray isArray |
1841 ifTrue: [annotationOrArray first == key ifTrue:[^index]] |
1841 ifTrue: [annotationOrArray first == key ifTrue:[^index]] |
1842 ifFalse:[annotationOrArray key == key ifTrue:[^index]]]. |
1842 ifFalse:[annotationOrArray key == key ifTrue:[^index]]]. |
1843 ^nil. |
1843 ^nil. |
1844 |
1844 |
1845 "Created: / 19-05-2010 / 16:40:32 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1845 "Created: / 19-05-2010 / 16:40:32 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1846 "Modified: / 11-07-2010 / 19:23:21 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1846 "Modified: / 11-07-2010 / 19:23:21 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
1847 ! |
1847 ! |
1850 "remember a (raw) source stream for later use" |
1850 "remember a (raw) source stream for later use" |
1851 |
1851 |
1852 |lastStream| |
1852 |lastStream| |
1853 |
1853 |
1854 (package notNil and:[package ~= PackageId noProjectID]) ifTrue:[ |
1854 (package notNil and:[package ~= PackageId noProjectID]) ifTrue:[ |
1855 LastFileLock critical:[ |
1855 LastFileLock critical:[ |
1856 lastStream := LastFileReference at:1. |
1856 lastStream := LastFileReference at:1. |
1857 (lastStream notNil and:[lastStream ~= 0 and:[lastStream isOpen]]) ifTrue:[ |
1857 (lastStream notNil and:[lastStream ~= 0 and:[lastStream isOpen]]) ifTrue:[ |
1858 lastStream close. |
1858 lastStream close. |
1859 ]. |
1859 ]. |
1860 LastSourceFileName := package,'/',source. |
1860 LastSourceFileName := package,'/',source. |
1861 LastFileReference at:1 put:aStream. |
1861 LastFileReference at:1 put:aStream. |
1862 ]. |
1862 ]. |
1863 ]. |
1863 ]. |
1864 ! |
1864 ! |
1865 |
1865 |
1866 getAnnotations |
1866 getAnnotations |
1867 |
1867 |
1883 searching in standard places." |
1883 searching in standard places." |
1884 |
1884 |
1885 |dir fileName aStream| |
1885 |dir fileName aStream| |
1886 |
1886 |
1887 package notNil ifTrue:[ |
1887 package notNil ifTrue:[ |
1888 "/ |
1888 "/ |
1889 "/ old: look in 'source/<filename>' |
1889 "/ old: look in 'source/<filename>' |
1890 "/ this is still kept in order to find user-private |
1890 "/ this is still kept in order to find user-private |
1891 "/ classes in her currentDirectory. |
1891 "/ classes in her currentDirectory. |
1892 "/ |
1892 "/ |
1893 fileName := Smalltalk getSourceFileName:(package copyReplaceAll:$: with:$/) , '/' , source. |
1893 fileName := Smalltalk getSourceFileName:(package copyReplaceAll:$: with:$/) , '/' , source. |
1894 fileName notNil ifTrue:[ |
1894 fileName notNil ifTrue:[ |
1895 aStream := fileName asFilename readStreamOrNil. |
1895 aStream := fileName asFilename readStreamOrNil. |
1896 aStream notNil ifTrue:[^ aStream]. |
1896 aStream notNil ifTrue:[^ aStream]. |
1897 ]. |
1897 ]. |
1898 "/ |
1898 "/ |
1899 "/ new: look in package-dir |
1899 "/ new: look in package-dir |
1900 "/ |
1900 "/ |
1901 dir := Smalltalk getPackageDirectoryForPackage:package. |
1901 dir := Smalltalk getPackageDirectoryForPackage:package. |
1902 dir notNil ifTrue:[ |
1902 dir notNil ifTrue:[ |
1903 fileName := dir construct:source. |
1903 fileName := dir construct:source. |
1904 aStream := fileName asFilename readStreamOrNil. |
1904 aStream := fileName asFilename readStreamOrNil. |
1905 aStream notNil ifTrue:[^ aStream]. |
1905 aStream notNil ifTrue:[^ aStream]. |
1906 ]. |
1906 ]. |
1907 ]. |
1907 ]. |
1908 fileName := Smalltalk getSourceFileName:source. |
1908 fileName := Smalltalk getSourceFileName:source. |
1909 fileName notNil ifTrue:[ |
1909 fileName notNil ifTrue:[ |
1910 aStream := fileName asFilename readStreamOrNil. |
1910 aStream := fileName asFilename readStreamOrNil. |
1911 ]. |
1911 ]. |
1912 ^ aStream |
1912 ^ aStream |
1913 ! |
1913 ! |
1914 |
1914 |
1915 rawSourceStreamUsingCache:usingCacheBoolean |
1915 rawSourceStreamUsingCache:usingCacheBoolean |
1927 " |
1927 " |
1928 source isNil ifTrue:[^ nil]. |
1928 source isNil ifTrue:[^ nil]. |
1929 sourcePosition isNil ifTrue:[^ source readStream]. |
1929 sourcePosition isNil ifTrue:[^ source readStream]. |
1930 |
1930 |
1931 usingCacheBoolean ifTrue:[ |
1931 usingCacheBoolean ifTrue:[ |
1932 (package notNil and:[package ~= PackageId noProjectID]) ifTrue:[ |
1932 (package notNil and:[package ~= PackageId noProjectID]) ifTrue:[ |
1933 "/ keep the last source file open, because open/close |
1933 "/ keep the last source file open, because open/close |
1934 "/ operations maybe slow on NFS-mounted file systems. |
1934 "/ operations maybe slow on NFS-mounted file systems. |
1935 "/ Since the reference to the file is weak, it will be closed |
1935 "/ Since the reference to the file is weak, it will be closed |
1936 "/ automatically if the file is not referenced for a while. |
1936 "/ automatically if the file is not referenced for a while. |
1937 "/ Neat trick. |
1937 "/ Neat trick. |
1938 |
1938 |
1939 LastFileLock critical:[ |
1939 LastFileLock critical:[ |
1940 aStream := LastFileReference at:1. |
1940 aStream := LastFileReference at:1. |
1941 (aStream isNil or:[aStream == 0 or:[aStream isOpen not]]) ifTrue:[ |
1941 (aStream isNil or:[aStream == 0 or:[aStream isOpen not]]) ifTrue:[ |
1942 aStream := nil. |
1942 aStream := nil. |
1943 LastFileReference at:1 put:nil. |
1943 LastFileReference at:1 put:nil. |
1944 ]. |
1944 ]. |
1945 (aStream notNil and:[LastSourceFileName ~= (package,'/',source)]) ifTrue:[ |
1945 (aStream notNil and:[LastSourceFileName ~= (package,'/',source)]) ifTrue:[ |
1946 aStream := nil. |
1946 aStream := nil. |
1947 ]. |
1947 ]. |
1948 ]. |
1948 ]. |
1949 |
1949 |
1950 aStream notNil ifTrue:[ |
1950 aStream notNil ifTrue:[ |
1951 ^ aStream |
1951 ^ aStream |
1952 ]. |
1952 ]. |
1953 ]. |
1953 ]. |
1954 ]. |
1954 ]. |
1955 |
1955 |
1956 "/ a negative sourcePosition indicates |
1956 "/ a negative sourcePosition indicates |
1957 "/ that this is a local file |
1957 "/ that this is a local file |
1958 "/ (not to be requested via the sourceCodeManager) |
1958 "/ (not to be requested via the sourceCodeManager) |
1959 "/ This kludge was added, to allow sourceCode to be |
1959 "/ This kludge was added, to allow sourceCode to be |
1960 "/ saved to a local source file (i.e. 'st.src') |
1960 "/ saved to a local source file (i.e. 'st.src') |
1961 "/ and having a clue for which file is meant later. |
1961 "/ and having a clue for which file is meant later. |
1962 |
1962 |
1963 sourcePosition < 0 ifTrue:[ |
1963 sourcePosition < 0 ifTrue:[ |
1964 aStream := source asFilename readStreamOrNil. |
1964 aStream := source asFilename readStreamOrNil. |
1965 aStream isNil ifTrue:[ |
1965 aStream isNil ifTrue:[ |
1966 "/ search in some standard places |
1966 "/ search in some standard places |
1967 fileName := Smalltalk getSourceFileName:source. |
1967 fileName := Smalltalk getSourceFileName:source. |
1968 fileName notNil ifTrue:[ |
1968 fileName notNil ifTrue:[ |
1969 aStream := fileName asFilename readStreamOrNil. |
1969 aStream := fileName asFilename readStreamOrNil. |
1970 ]. |
1970 ]. |
1971 ]. |
1971 ]. |
1972 aStream notNil ifTrue:[ |
1972 aStream notNil ifTrue:[ |
1973 usingCacheBoolean ifTrue:[ |
1973 usingCacheBoolean ifTrue:[ |
1974 self cacheSourceStream:aStream. |
1974 self cacheSourceStream:aStream. |
1975 ]. |
1975 ]. |
1976 ^ aStream |
1976 ^ aStream |
1977 ]. |
1977 ]. |
1978 ]. |
1978 ]. |
1979 |
1979 |
1980 "/ |
1980 "/ |
1981 "/ if there is no SourceManager, look in local standard places first |
1981 "/ if there is no SourceManager, look in local standard places first |
1982 "/ |
1982 "/ |
1983 (Class tryLocalSourceFirst or:[(mgr := Smalltalk at:#SourceCodeManager) isNil]) ifTrue:[ |
1983 (Class tryLocalSourceFirst or:[(mgr := Smalltalk at:#SourceCodeManager) isNil]) ifTrue:[ |
1984 aStream := self localSourceStream. |
1984 aStream := self localSourceStream. |
1985 aStream notNil ifTrue:[ |
1985 aStream notNil ifTrue:[ |
1986 usingCacheBoolean ifTrue:[ |
1986 usingCacheBoolean ifTrue:[ |
1987 self cacheSourceStream:aStream. |
1987 self cacheSourceStream:aStream. |
1988 ]. |
1988 ]. |
1989 ^ aStream |
1989 ^ aStream |
1990 ]. |
1990 ]. |
1991 ]. |
1991 ]. |
1992 |
1992 |
1993 "/ |
1993 "/ |
1994 "/ nope - ask my class for the source (this also invokes the SCMgr) |
1994 "/ nope - ask my class for the source (this also invokes the SCMgr) |
1995 "/ |
1995 "/ |
1996 who := self who. |
1996 who := self who. |
1997 who notNil ifTrue:[ |
1997 who notNil ifTrue:[ |
1998 myClass := who methodClass. |
1998 myClass := who methodClass. |
1999 |
1999 |
2000 (package notNil and:[package ~= myClass package]) ifTrue:[ |
2000 (package notNil and:[package ~= myClass package]) ifTrue:[ |
2001 "/ I am an extension |
2001 "/ I am an extension |
2002 mgr notNil ifTrue:[ |
2002 mgr notNil ifTrue:[ |
2003 "/ try to get the source using my package information ... |
2003 "/ try to get the source using my package information ... |
2004 mod := package asPackageId module. |
2004 mod := package asPackageId module. |
2005 dir := package asPackageId directory. |
2005 dir := package asPackageId directory. |
2006 aStream := mgr streamForExtensionFile:source package:package directory:dir module:mod cache:true. |
2006 aStream := mgr streamForExtensionFile:source package:package directory:dir module:mod cache:true. |
2007 aStream notNil ifTrue:[ |
2007 aStream notNil ifTrue:[ |
2008 usingCacheBoolean ifTrue:[ |
2008 usingCacheBoolean ifTrue:[ |
2009 self cacheSourceStream:aStream. |
2009 self cacheSourceStream:aStream. |
2010 ]. |
2010 ]. |
2011 ^ aStream |
2011 ^ aStream |
2012 ]. |
2012 ]. |
2013 ]. |
2013 ]. |
2014 "/ consult the local fileSystem |
2014 "/ consult the local fileSystem |
2015 aStream := self localSourceStream. |
2015 aStream := self localSourceStream. |
2016 aStream notNil ifTrue:[ |
2016 aStream notNil ifTrue:[ |
2017 usingCacheBoolean ifTrue:[ |
2017 usingCacheBoolean ifTrue:[ |
2018 self cacheSourceStream:aStream. |
2018 self cacheSourceStream:aStream. |
2019 ]. |
2019 ]. |
2020 ^ aStream |
2020 ^ aStream |
2021 ] |
2021 ] |
2022 ]. |
2022 ]. |
2023 |
2023 |
2024 aStream := myClass sourceStreamFor:source. |
2024 aStream := myClass sourceStreamFor:source. |
2025 aStream notNil ifTrue:[ |
2025 aStream notNil ifTrue:[ |
2026 usingCacheBoolean ifTrue:[ |
2026 usingCacheBoolean ifTrue:[ |
2027 self cacheSourceStream:aStream. |
2027 self cacheSourceStream:aStream. |
2028 ]. |
2028 ]. |
2029 ^ aStream |
2029 ^ aStream |
2030 ]. |
2030 ]. |
2031 ]. |
2031 ]. |
2032 |
2032 |
2033 "/ |
2033 "/ |
2034 "/ nope - look in standard places |
2034 "/ nope - look in standard places |
2035 "/ (if there is a source-code manager - otherwise, we already did that) |
2035 "/ (if there is a source-code manager - otherwise, we already did that) |
2036 "/ |
2036 "/ |
2037 (mgr notNil and:[Class tryLocalSourceFirst not]) ifTrue:[ |
2037 (mgr notNil and:[Class tryLocalSourceFirst not]) ifTrue:[ |
2038 aStream := self localSourceStream. |
2038 aStream := self localSourceStream. |
2039 aStream notNil ifTrue:[ |
2039 aStream notNil ifTrue:[ |
2040 usingCacheBoolean ifTrue:[ |
2040 usingCacheBoolean ifTrue:[ |
2041 self cacheSourceStream:aStream. |
2041 self cacheSourceStream:aStream. |
2042 ]. |
2042 ]. |
2043 ^ aStream |
2043 ^ aStream |
2044 ]. |
2044 ]. |
2045 ]. |
2045 ]. |
2046 |
2046 |
2047 "/ |
2047 "/ |
2048 "/ final chance: try current directory |
2048 "/ final chance: try current directory |
2049 "/ |
2049 "/ |
2050 aStream isNil ifTrue:[ |
2050 aStream isNil ifTrue:[ |
2051 aStream := source asFilename readStreamOrNil. |
2051 aStream := source asFilename readStreamOrNil. |
2052 aStream notNil ifTrue:[ |
2052 aStream notNil ifTrue:[ |
2053 usingCacheBoolean ifTrue:[ |
2053 usingCacheBoolean ifTrue:[ |
2054 self cacheSourceStream:aStream. |
2054 self cacheSourceStream:aStream. |
2055 ]. |
2055 ]. |
2056 ^ aStream |
2056 ^ aStream |
2057 ]. |
2057 ]. |
2058 ]. |
2058 ]. |
2059 |
2059 |
2060 (who isNil and:[source notNil]) ifTrue:[ |
2060 (who isNil and:[source notNil]) ifTrue:[ |
2061 "/ |
2061 "/ |
2062 "/ mhmh - seems to be a method which used to be in some |
2062 "/ mhmh - seems to be a method which used to be in some |
2063 "/ class, but has been overwritten by another or removed. |
2063 "/ class, but has been overwritten by another or removed. |
2064 "/ (i.e. it has no containing class anyMore) |
2064 "/ (i.e. it has no containing class anyMore) |
2065 "/ try to guess the class from the sourceFileName. |
2065 "/ try to guess the class from the sourceFileName. |
2066 "/ and retry. |
2066 "/ and retry. |
2067 "/ |
2067 "/ |
2068 className := Smalltalk classNameForFile:source. |
2068 className := Smalltalk classNameForFile:source. |
2069 (classNameSymbol := className asSymbolIfInterned) notNil ifTrue:[ |
2069 (classNameSymbol := className asSymbolIfInterned) notNil ifTrue:[ |
2070 myClass := Smalltalk at:classNameSymbol ifAbsent:nil. |
2070 myClass := Smalltalk at:classNameSymbol ifAbsent:nil. |
2071 myClass notNil ifTrue:[ |
2071 myClass notNil ifTrue:[ |
2072 aStream := myClass sourceStreamFor:source. |
2072 aStream := myClass sourceStreamFor:source. |
2073 aStream notNil ifTrue:[ |
2073 aStream notNil ifTrue:[ |
2074 usingCacheBoolean ifTrue:[ |
2074 usingCacheBoolean ifTrue:[ |
2075 self cacheSourceStream:aStream. |
2075 self cacheSourceStream:aStream. |
2076 ]. |
2076 ]. |
2077 ^ aStream |
2077 ^ aStream |
2078 ]. |
2078 ]. |
2079 ] |
2079 ] |
2080 ] |
2080 ] |
2081 ]. |
2081 ]. |
2082 |
2082 |
2083 ^ nil |
2083 ^ nil |
2084 |
2084 |
2085 "Modified: / 26-11-2006 / 22:33:38 / cg" |
2085 "Modified: / 26-11-2006 / 22:33:38 / cg" |
2094 "Created: / 11-07-2010 / 19:31:59 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
2094 "Created: / 11-07-2010 / 19:31:59 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
2095 ! |
2095 ! |
2096 |
2096 |
2097 sourceChunkFromStream:aStream |
2097 sourceChunkFromStream:aStream |
2098 PositionError handle:[:ex | |
2098 PositionError handle:[:ex | |
2099 ^ nil |
2099 ^ nil |
2100 ] do:[ |
2100 ] do:[ |
2101 aStream position1Based:(sourcePosition ? 1) abs. |
2101 aStream position1Based:(sourcePosition ? 1) abs. |
2102 ]. |
2102 ]. |
2103 ^ aStream nextChunk. |
2103 ^ aStream nextChunk. |
2104 ! |
2104 ! |
2105 |
2105 |
2106 sourceStreamUsingCache:usingCacheBoolean |
2106 sourceStreamUsingCache:usingCacheBoolean |
2111 |
2111 |
2112 |rawStream| |
2112 |rawStream| |
2113 |
2113 |
2114 rawStream := self rawSourceStreamUsingCache:usingCacheBoolean. |
2114 rawStream := self rawSourceStreamUsingCache:usingCacheBoolean. |
2115 rawStream isNil ifTrue:[ |
2115 rawStream isNil ifTrue:[ |
2116 ^ nil. |
2116 ^ nil. |
2117 ]. |
2117 ]. |
2118 |
2118 |
2119 "/ see if its utf8 encoded... |
2119 "/ see if its utf8 encoded... |
2120 ^ EncodedStream decodedStreamFor:rawStream. |
2120 ^ EncodedStream decodedStreamFor:rawStream. |
2121 ! ! |
2121 ! ! |
2131 #ifdef F_PRIMITIVE |
2131 #ifdef F_PRIMITIVE |
2132 INT f = __intVal(__INST(flags)); |
2132 INT f = __intVal(__INST(flags)); |
2133 OBJ nr = 0; |
2133 OBJ nr = 0; |
2134 |
2134 |
2135 if (f & F_PRIMITIVE) { |
2135 if (f & F_PRIMITIVE) { |
2136 nr = __INST(code_); |
2136 nr = __INST(code_); |
2137 } |
2137 } |
2138 RETURN (nr); |
2138 RETURN (nr); |
2139 #endif |
2139 #endif |
2140 %}. |
2140 %}. |
2141 self primitiveFailed |
2141 self primitiveFailed |
2185 |
2185 |
2186 |src parser| |
2186 |src parser| |
2187 |
2187 |
2188 src := self source. |
2188 src := self source. |
2189 src notNil ifTrue:[ |
2189 src notNil ifTrue:[ |
2190 parser := Parser |
2190 parser := Parser |
2191 parseMethod:src |
2191 parseMethod:src |
2192 in:self containingClass |
2192 in:self containingClass |
2193 ignoreErrors:true |
2193 ignoreErrors:true |
2194 ignoreWarnings:true. |
2194 ignoreWarnings:true. |
2195 |
2195 |
2196 (parser notNil and:[parser ~~ #Error]) ifTrue:[ |
2196 (parser notNil and:[parser ~~ #Error]) ifTrue:[ |
2197 ^ parser usedInstVars |
2197 ^ parser usedInstVars |
2198 ]. |
2198 ]. |
2199 ]. |
2199 ]. |
2200 ^ #() "/ actually: unknown |
2200 ^ #() "/ actually: unknown |
2201 |
2201 |
2202 "Modified: 19.6.1997 / 17:54:09 / cg" |
2202 "Modified: 19.6.1997 / 17:54:09 / cg" |
2203 ! |
2203 ! |
2209 "based on who, which has been added for ST-80 compatibility" |
2209 "based on who, which has been added for ST-80 compatibility" |
2210 |
2210 |
2211 |who| |
2211 |who| |
2212 |
2212 |
2213 mclass notNil ifTrue:[ |
2213 mclass notNil ifTrue:[ |
2214 "/ check if this (cached) info is still valid ... |
2214 "/ check if this (cached) info is still valid ... |
2215 (mclass containsMethod:self) ifTrue:[ |
2215 (mclass containsMethod:self) ifTrue:[ |
2216 ^ mclass |
2216 ^ mclass |
2217 ]. |
2217 ]. |
2218 mclass := nil. |
2218 mclass := nil. |
2219 ]. |
2219 ]. |
2220 |
2220 |
2221 who := self who. |
2221 who := self who. |
2222 who notNil ifTrue:[^ who methodClass]. |
2222 who notNil ifTrue:[^ who methodClass]. |
2223 " |
2223 " |
2236 "if this is an externalLibraryFunction call, return the externalLibraryFunction. |
2236 "if this is an externalLibraryFunction call, return the externalLibraryFunction. |
2237 Returns nil otherwise." |
2237 Returns nil otherwise." |
2238 |
2238 |
2239 |newMethod function| |
2239 |newMethod function| |
2240 |
2240 |
2241 (self |
2241 (self |
2242 literalsDetect:[:lit | |
2242 literalsDetect:[:lit | |
2243 #( |
2243 #( |
2244 #'invoke' |
2244 #'invoke' |
2245 #'invokeWith:' |
2245 #'invokeWith:' |
2246 #'invokeWith:with:' |
2246 #'invokeWith:with:' |
2247 #'invokeWith:with:with:' |
2247 #'invokeWith:with:with:' |
2248 #'invokeWith:with:with:with:' |
2248 #'invokeWith:with:with:with:' |
2249 #'invokeWithArguments:' |
2249 #'invokeWithArguments:' |
2250 #'invokeCPPVirtualOn:' |
2250 #'invokeCPPVirtualOn:' |
2251 #'invokeCPPVirtualOn:with:' |
2251 #'invokeCPPVirtualOn:with:' |
2252 #'invokeCPPVirtualOn:with:with:' |
2252 #'invokeCPPVirtualOn:with:with:' |
2253 #'invokeCPPVirtualOn:with:with:with:' |
2253 #'invokeCPPVirtualOn:with:with:with:' |
2254 #'invokeCPPVirtualOn:with:with:with:with:' |
2254 #'invokeCPPVirtualOn:with:with:with:with:' |
2255 #'invokeCPPVirtualOn:withArguments:' |
2255 #'invokeCPPVirtualOn:withArguments:' |
2256 ) includes:lit |
2256 ) includes:lit |
2257 ] |
2257 ] |
2258 ifNone:nil) notNil |
2258 ifNone:nil) notNil |
2259 ifTrue:[ |
2259 ifTrue:[ |
2260 "/ sigh - for stc-compiled code, this does not work: |
2260 "/ sigh - for stc-compiled code, this does not work: |
2261 function := self literalsDetect:[:lit | lit isExternalLibraryFunction] ifNone:nil. |
2261 function := self literalsDetect:[:lit | lit isExternalLibraryFunction] ifNone:nil. |
2262 function isNil ifTrue:[ |
2262 function isNil ifTrue:[ |
2263 "/ parse it and ask the parser |
2263 "/ parse it and ask the parser |
2264 newMethod := Compiler compile:self source forClass:self mclass install:false. |
2264 newMethod := Compiler compile:self source forClass:self mclass install:false. |
2265 function := newMethod literalsDetect:[:lit | lit isExternalLibraryFunction] ifNone:nil. |
2265 function := newMethod literalsDetect:[:lit | lit isExternalLibraryFunction] ifNone:nil. |
2266 ]. |
2266 ]. |
2267 ^ function |
2267 ^ function |
2268 ]. |
2268 ]. |
2269 ^ nil |
2269 ^ nil |
2270 |
2270 |
2271 " |
2271 " |
2272 (IDispatchPointer compiledMethodAt:#'invokeGetTypeInfo:_:_:') |
2272 (IDispatchPointer compiledMethodAt:#'invokeGetTypeInfo:_:_:') |
2273 externalLibraryFunction |
2273 externalLibraryFunction |
2274 " |
2274 " |
2275 ! |
2275 ! |
2276 |
2276 |
2277 hasAnnotation |
2277 hasAnnotation |
2278 |
2278 |
2298 |
2298 |
2299 ^ self hasResource and:[ self resources keys includesAny:aCollectionOfSymbols ] |
2299 ^ self hasResource and:[ self resources keys includesAny:aCollectionOfSymbols ] |
2300 |
2300 |
2301 " |
2301 " |
2302 Method allInstancesDo:[:m | |
2302 Method allInstancesDo:[:m | |
2303 (m hasAnyResource:#(image canvas)) ifTrue:[self halt] |
2303 (m hasAnyResource:#(image canvas)) ifTrue:[self halt] |
2304 ]. |
2304 ]. |
2305 " |
2305 " |
2306 ! |
2306 ! |
2307 |
2307 |
2308 hasCanvasResource |
2308 hasCanvasResource |
2335 "/ first a trivial reject, if the source does not |
2335 "/ first a trivial reject, if the source does not |
2336 "/ contain a '% {' sequence |
2336 "/ contain a '% {' sequence |
2337 |
2337 |
2338 src := self source. |
2338 src := self source. |
2339 src notNil ifTrue:[ |
2339 src notNil ifTrue:[ |
2340 (src includesString:(String with:$% with:${) "<- no constant here - to avoid trouble with stupid scanners" ) ifFalse:[ |
2340 (src includesString:(String with:$% with:${) "<- no constant here - to avoid trouble with stupid scanners" ) ifFalse:[ |
2341 "/ cannot contain primitive code. |
2341 "/ cannot contain primitive code. |
2342 ^ false |
2342 ^ false |
2343 ] |
2343 ] |
2344 ]. |
2344 ]. |
2345 |
2345 |
2346 "/ ok; it may or may not ... |
2346 "/ ok; it may or may not ... |
2347 |
2347 |
2348 ^ self parse:#'parseMethodSilent:' return:#hasPrimitiveCode or:false |
2348 ^ self parse:#'parseMethodSilent:' return:#hasPrimitiveCode or:false |
2374 |
2374 |
2375 ^ self hasResource and:[ (self resources ? #()) includesKey:aSymbol ] |
2375 ^ self hasResource and:[ (self resources ? #()) includesKey:aSymbol ] |
2376 |
2376 |
2377 " |
2377 " |
2378 Method allInstancesDo:[:m | |
2378 Method allInstancesDo:[:m | |
2379 (m hasResource:#image) ifTrue:[self halt] |
2379 (m hasResource:#image) ifTrue:[self halt] |
2380 ]. |
2380 ]. |
2381 " |
2381 " |
2382 |
2382 |
2383 "Modified: / 01-12-2010 / 13:59:58 / cg" |
2383 "Modified: / 01-12-2010 / 13:59:58 / cg" |
2384 ! |
2384 ! |
2447 |
2447 |
2448 myCode := self code. |
2448 myCode := self code. |
2449 |
2449 |
2450 m := self trapMethodForNumArgs:(self numArgs). |
2450 m := self trapMethodForNumArgs:(self numArgs). |
2451 (m notNil and:[self ~~ m]) ifTrue:[ |
2451 (m notNil and:[self ~~ m]) ifTrue:[ |
2452 (myCode notNil and:[myCode = m code]) ifTrue:[^ true]. |
2452 (myCode notNil and:[myCode = m code]) ifTrue:[^ true]. |
2453 (byteCode notNil and:[byteCode == m byteCode]) ifTrue:[^ true]. |
2453 (byteCode notNil and:[byteCode == m byteCode]) ifTrue:[^ true]. |
2454 ]. |
2454 ]. |
2455 |
2455 |
2456 m := Method compiledMethodAt:#uncompiledCodeObject. |
2456 m := Method compiledMethodAt:#uncompiledCodeObject. |
2457 (m notNil and:[self ~~ m]) ifTrue:[ |
2457 (m notNil and:[self ~~ m]) ifTrue:[ |
2458 (myCode notNil and:[myCode = m code]) ifTrue:[^ true]. |
2458 (myCode notNil and:[myCode = m code]) ifTrue:[^ true]. |
2459 (byteCode notNil and:[byteCode == m byteCode]) ifTrue:[^ true]. |
2459 (byteCode notNil and:[byteCode == m byteCode]) ifTrue:[^ true]. |
2460 ]. |
2460 ]. |
2461 |
2461 |
2462 m := Method compiledMethodAt:#unloadedCodeObject. |
2462 m := Method compiledMethodAt:#unloadedCodeObject. |
2463 (m notNil and:[self ~~ m]) ifTrue:[ |
2463 (m notNil and:[self ~~ m]) ifTrue:[ |
2464 (myCode notNil and:[myCode = m code]) ifTrue:[^ true]. |
2464 (myCode notNil and:[myCode = m code]) ifTrue:[^ true]. |
2465 (byteCode notNil and:[byteCode == m byteCode]) ifTrue:[^ true]. |
2465 (byteCode notNil and:[byteCode == m byteCode]) ifTrue:[^ true]. |
2466 ]. |
2466 ]. |
2467 |
2467 |
2468 ^ false |
2468 ^ false |
2469 |
2469 |
2470 "Modified: 4.11.1996 / 23:34:24 / cg" |
2470 "Modified: 4.11.1996 / 23:34:24 / cg" |
2581 |parserClass parser sourceString argNames varNames| |
2581 |parserClass parser sourceString argNames varNames| |
2582 |
2582 |
2583 parserClass := self parserClass. |
2583 parserClass := self parserClass. |
2584 sourceString := self source. |
2584 sourceString := self source. |
2585 (parserClass notNil and:[sourceString notNil]) ifTrue:[ |
2585 (parserClass notNil and:[sourceString notNil]) ifTrue:[ |
2586 parser := parserClass parseMethodArgAndVarSpecificationSilent:sourceString. |
2586 parser := parserClass parseMethodArgAndVarSpecificationSilent:sourceString. |
2587 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
2587 (parser isNil or:[parser == #Error]) ifTrue:[^ nil]. |
2588 argNames := parser methodArgs. |
2588 argNames := parser methodArgs. |
2589 varNames := parser methodVars. |
2589 varNames := parser methodVars. |
2590 argNames isNil ifTrue:[^ varNames]. |
2590 argNames isNil ifTrue:[^ varNames]. |
2591 varNames isNil ifTrue:[^ argNames]. |
2591 varNames isNil ifTrue:[^ argNames]. |
2592 ^ (argNames , varNames) |
2592 ^ (argNames , varNames) |
2593 ]. |
2593 ]. |
2594 ^ nil |
2594 ^ nil |
2595 |
2595 |
2596 " |
2596 " |
2597 (Method compiledMethodAt:#printOn:) methodArgAndVarNames |
2597 (Method compiledMethodAt:#printOn:) methodArgAndVarNames |
2621 (text size < 2) ifTrue:[^nil]. |
2621 (text size < 2) ifTrue:[^nil]. |
2622 |
2622 |
2623 line := (text at:2). |
2623 line := (text at:2). |
2624 nQuote := line occurrencesOf:(Character doubleQuote). |
2624 nQuote := line occurrencesOf:(Character doubleQuote). |
2625 (nQuote == 2) ifTrue:[ |
2625 (nQuote == 2) ifTrue:[ |
2626 qIndex := line indexOf:(Character doubleQuote). |
2626 qIndex := line indexOf:(Character doubleQuote). |
2627 qIndex2 := line indexOf:(Character doubleQuote) startingAt:(qIndex + 1). |
2627 qIndex2 := line indexOf:(Character doubleQuote) startingAt:(qIndex + 1). |
2628 ^ line copyFrom:(qIndex + 1) to:(qIndex2 - 1) |
2628 ^ line copyFrom:(qIndex + 1) to:(qIndex2 - 1) |
2629 ]. |
2629 ]. |
2630 (nQuote == 1) ifTrue:[ |
2630 (nQuote == 1) ifTrue:[ |
2631 qIndex := line indexOf:(Character doubleQuote). |
2631 qIndex := line indexOf:(Character doubleQuote). |
2632 comment := line copyFrom:(qIndex + 1). |
2632 comment := line copyFrom:(qIndex + 1). |
2633 (line indexOf:$/ startingAt:qIndex) == (qIndex+1) ifTrue:[ |
2633 (line indexOf:$/ startingAt:qIndex) == (qIndex+1) ifTrue:[ |
2634 "/ an EOL comment |
2634 "/ an EOL comment |
2635 ^ (comment copyFrom:2) withoutSeparators |
2635 ^ (comment copyFrom:2) withoutSeparators |
2636 ]. |
2636 ]. |
2637 |
2637 |
2638 "/ not an EOL comment |
2638 "/ not an EOL comment |
2639 index := 3. |
2639 index := 3. |
2640 line := text at:index. |
2640 line := text at:index. |
2641 nQuote := line occurrencesOf:(Character doubleQuote). |
2641 nQuote := line occurrencesOf:(Character doubleQuote). |
2642 [nQuote ~~ 1] whileTrue:[ |
2642 [nQuote ~~ 1] whileTrue:[ |
2643 comment := comment , Character cr asString , line withoutSpaces. |
2643 comment := comment , Character cr asString , line withoutSpaces. |
2644 index := index + 1. |
2644 index := index + 1. |
2645 line := text at:index. |
2645 line := text at:index. |
2646 nQuote := line occurrencesOf:(Character doubleQuote) |
2646 nQuote := line occurrencesOf:(Character doubleQuote) |
2647 ]. |
2647 ]. |
2648 qIndex := line indexOf:(Character doubleQuote). |
2648 qIndex := line indexOf:(Character doubleQuote). |
2649 ^ comment , Character cr asString , (line copyTo:(qIndex - 1)) withoutSpaces |
2649 ^ comment , Character cr asString , (line copyTo:(qIndex - 1)) withoutSpaces |
2650 ]. |
2650 ]. |
2651 ^ nil |
2651 ^ nil |
2652 |
2652 |
2653 " |
2653 " |
2654 (Method compiledMethodAt:#methodComment) methodComment |
2654 (Method compiledMethodAt:#methodComment) methodComment |
2657 |
2657 |
2658 methodDefinitionTemplate |
2658 methodDefinitionTemplate |
2659 "return the string that defines the method and the arguments" |
2659 "return the string that defines the method and the arguments" |
2660 |
2660 |
2661 ^ Method |
2661 ^ Method |
2662 methodDefinitionTemplateForSelector:self selector |
2662 methodDefinitionTemplateForSelector:self selector |
2663 andArgumentNames:self methodArgNames |
2663 andArgumentNames:self methodArgNames |
2664 |
2664 |
2665 " |
2665 " |
2666 (self compiledMethodAt:#printOn:) methodDefinitionTemplate |
2666 (self compiledMethodAt:#printOn:) methodDefinitionTemplate |
2667 " |
2667 " |
2668 ! |
2668 ! |
2699 s isNil ifTrue:[^ nil]. |
2699 s isNil ifTrue:[^ nil]. |
2700 list := HistoryManager getAllHistoriesFrom:s. |
2700 list := HistoryManager getAllHistoriesFrom:s. |
2701 list size == 0 ifTrue:[^ nil]. |
2701 list size == 0 ifTrue:[^ nil]. |
2702 histLine := list last. |
2702 histLine := list last. |
2703 ^ Timestamp |
2703 ^ Timestamp |
2704 fromDate:histLine date |
2704 fromDate:histLine date |
2705 andTime:histLine time |
2705 andTime:histLine time |
2706 |
2706 |
2707 " |
2707 " |
2708 (Method compiledMethodAt:#modificationTime) modificationTime |
2708 (Method compiledMethodAt:#modificationTime) modificationTime |
2709 (Method compiledMethodAt:#isMethod) modificationTime |
2709 (Method compiledMethodAt:#isMethod) modificationTime |
2710 " |
2710 " |
2724 overrides: aMethod |
2724 overrides: aMethod |
2725 |
2725 |
2726 | mth | |
2726 | mth | |
2727 mth := self overriddenMethod. |
2727 mth := self overriddenMethod. |
2728 [ mth notNil ] whileTrue: |
2728 [ mth notNil ] whileTrue: |
2729 [mth == aMethod ifTrue:[^true]. |
2729 [mth == aMethod ifTrue:[^true]. |
2730 mth := mth overriddenMethod]. |
2730 mth := mth overriddenMethod]. |
2731 ^false |
2731 ^false |
2732 |
2732 |
2733 "Modified: / 18-06-2009 / 12:15:53 / Jan Vrany <vranyj1@fel.cvut.cz>" |
2733 "Modified: / 18-06-2009 / 12:15:53 / Jan Vrany <vranyj1@fel.cvut.cz>" |
2734 ! |
2734 ! |
2735 |
2735 |
2740 |
2740 |
2741 ^ self parse:parseSelector with:nil return:accessSelector or:valueIfNoSource |
2741 ^ self parse:parseSelector with:nil return:accessSelector or:valueIfNoSource |
2742 |
2742 |
2743 " |
2743 " |
2744 (Method compiledMethodAt:#parse:return:or:) |
2744 (Method compiledMethodAt:#parse:return:or:) |
2745 parse:#'parseMethodSilent:' return:#sentMessages or:#() |
2745 parse:#'parseMethodSilent:' return:#sentMessages or:#() |
2746 " |
2746 " |
2747 ! |
2747 ! |
2748 |
2748 |
2749 parse:parseSelector with:arg2 return:accessSelector or:valueIfNoSource |
2749 parse:parseSelector with:arg2 return:accessSelector or:valueIfNoSource |
2750 "helper for methodArgNames, methodVarNames etc. |
2750 "helper for methodArgNames, methodVarNames etc. |
2754 |parser parserClass sourceString| |
2754 |parser parserClass sourceString| |
2755 |
2755 |
2756 parserClass := self parserClass. |
2756 parserClass := self parserClass. |
2757 sourceString := self source. |
2757 sourceString := self source. |
2758 (parserClass notNil and:[sourceString notNil]) ifTrue:[ |
2758 (parserClass notNil and:[sourceString notNil]) ifTrue:[ |
2759 parseSelector numArgs == 2 ifTrue:[ |
2759 parseSelector numArgs == 2 ifTrue:[ |
2760 parser := parserClass perform:parseSelector with:sourceString with:arg2. |
2760 parser := parserClass perform:parseSelector with:sourceString with:arg2. |
2761 ] ifFalse:[ |
2761 ] ifFalse:[ |
2762 parser := parserClass perform:parseSelector with:sourceString. |
2762 parser := parserClass perform:parseSelector with:sourceString. |
2763 ]. |
2763 ]. |
2764 (parser isNil or:[parser == #Error]) ifTrue:[^ valueIfNoSource]. |
2764 (parser isNil or:[parser == #Error]) ifTrue:[^ valueIfNoSource]. |
2765 ^ parser perform:accessSelector |
2765 ^ parser perform:accessSelector |
2766 ]. |
2766 ]. |
2767 ^ valueIfNoSource |
2767 ^ valueIfNoSource |
2768 |
2768 |
2769 " |
2769 " |
2770 (Method compiledMethodAt:#parse:return:or:) |
2770 (Method compiledMethodAt:#parse:return:or:) |
2771 parse:#'parseMethodSilent:' return:#sentMessages or:#() |
2771 parse:#'parseMethodSilent:' return:#sentMessages or:#() |
2772 " |
2772 " |
2773 ! |
2773 ! |
2774 |
2774 |
2775 parseAnnotations |
2775 parseAnnotations |
2776 |
2776 |
2778 |
2778 |
2779 |src parser| |
2779 |src parser| |
2780 |
2780 |
2781 src := self source. |
2781 src := self source. |
2782 src isNil ifTrue:[ |
2782 src isNil ifTrue:[ |
2783 ^ nil "/ actually: dont know |
2783 ^ nil "/ actually: dont know |
2784 ]. |
2784 ]. |
2785 |
2785 |
2786 self parserClass isNil ifTrue:[ |
2786 self parserClass isNil ifTrue:[ |
2787 ^ nil |
2787 ^ nil |
2788 ]. |
2788 ]. |
2789 parser := self parserClass parseMethod: src. |
2789 parser := self parserClass parseMethod: src. |
2790 (parser isNil or: [parser == #Error]) ifTrue:[ |
2790 (parser isNil or: [parser == #Error]) ifTrue:[ |
2791 ^ nil "/ actually error |
2791 ^ nil "/ actually error |
2792 ]. |
2792 ]. |
2793 ^ annotations := parser annotations. |
2793 ^ annotations := parser annotations. |
2794 |
2794 |
2795 "Created: / 10-07-2010 / 21:16:46 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
2795 "Created: / 10-07-2010 / 21:16:46 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
2796 ! |
2796 ! |
2800 |
2800 |
2801 |src parser| |
2801 |src parser| |
2802 |
2802 |
2803 src := self source. |
2803 src := self source. |
2804 src isNil ifTrue:[ |
2804 src isNil ifTrue:[ |
2805 ^ nil "/ actually: dont know |
2805 ^ nil "/ actually: dont know |
2806 ]. |
2806 ]. |
2807 |
2807 |
2808 (src findString:'resource:') == 0 ifTrue:[ |
2808 (src findString:'resource:') == 0 ifTrue:[ |
2809 ^ nil "/ actually: error |
2809 ^ nil "/ actually: error |
2810 ]. |
2810 ]. |
2811 "/ no need to parse all - only interested in resource-info |
2811 "/ no need to parse all - only interested in resource-info |
2812 self parserClass isNil ifTrue:[ |
2812 self parserClass isNil ifTrue:[ |
2813 ^ nil |
2813 ^ nil |
2814 ]. |
2814 ]. |
2815 parser := self parserClass parseMethodArgAndVarSpecificationSilent:src in:nil. |
2815 parser := self parserClass parseMethodArgAndVarSpecificationSilent:src in:nil. |
2816 parser isNil ifTrue:[ |
2816 parser isNil ifTrue:[ |
2817 ^ nil "/ actually error |
2817 ^ nil "/ actually error |
2818 ]. |
2818 ]. |
2819 ^ parser primitiveResources. |
2819 ^ parser primitiveResources. |
2820 ! |
2820 ! |
2821 |
2821 |
2822 previousVersion |
2822 previousVersion |
2829 |
2829 |
2830 cls := self mclass. |
2830 cls := self mclass. |
2831 cls isNil ifTrue:[ ^ nil ]. |
2831 cls isNil ifTrue:[ ^ nil ]. |
2832 |
2832 |
2833 ChangeSet current reverseDo:[:change | |
2833 ChangeSet current reverseDo:[:change | |
2834 (change isMethodChange |
2834 (change isMethodChange |
2835 and:[ (change selector == sel) |
2835 and:[ (change selector == sel) |
2836 and:[ change changeClass == cls ]]) |
2836 and:[ change changeClass == cls ]]) |
2837 ifTrue:[ |
2837 ifTrue:[ |
2838 previous := change previousVersion. |
2838 previous := change previousVersion. |
2839 previous notNil ifTrue:[ |
2839 previous notNil ifTrue:[ |
2840 ^ previous |
2840 ^ previous |
2841 ] |
2841 ] |
2842 ] |
2842 ] |
2843 ]. |
2843 ]. |
2844 ^ nil. |
2844 ^ nil. |
2845 |
2845 |
2846 "/ history := Class methodHistory. |
2846 "/ history := Class methodHistory. |
2847 "/ history isNil ifTrue:[^ nil]. |
2847 "/ history isNil ifTrue:[^ nil]. |
2887 cls isNil ifTrue:[^ #()]. |
2887 cls isNil ifTrue:[^ #()]. |
2888 |
2888 |
2889 versions := OrderedCollection new. |
2889 versions := OrderedCollection new. |
2890 |
2890 |
2891 ChangeSet current reverseDo:[:change | |
2891 ChangeSet current reverseDo:[:change | |
2892 (change isMethodChange |
2892 (change isMethodChange |
2893 and:[ (change selector == sel) |
2893 and:[ (change selector == sel) |
2894 and:[ change changeClass == cls ]]) |
2894 and:[ change changeClass == cls ]]) |
2895 ifTrue:[ |
2895 ifTrue:[ |
2896 versions addFirst:change. |
2896 versions addFirst:change. |
2897 lastChange := change. |
2897 lastChange := change. |
2898 ] |
2898 ] |
2899 ]. |
2899 ]. |
2900 |
2900 |
2901 lastChange notNil ifTrue:[ |
2901 lastChange notNil ifTrue:[ |
2902 last := lastChange previousVersion. |
2902 last := lastChange previousVersion. |
2903 last notNil ifTrue:[ |
2903 last notNil ifTrue:[ |
2904 firstSrc := last source. |
2904 firstSrc := last source. |
2905 (firstSrc size > 0 |
2905 (firstSrc size > 0 |
2906 and:[ firstSrc ~= lastChange source]) ifTrue:[ |
2906 and:[ firstSrc ~= lastChange source]) ifTrue:[ |
2907 versions addFirst:(MethodChange |
2907 versions addFirst:(MethodChange |
2908 className:lastChange className |
2908 className:lastChange className |
2909 selector:lastChange selector |
2909 selector:lastChange selector |
2910 source:firstSrc |
2910 source:firstSrc |
2911 category:lastChange category). |
2911 category:lastChange category). |
2912 ] |
2912 ] |
2913 ] |
2913 ] |
2914 ]. |
2914 ]. |
2915 ^ versions |
2915 ^ versions |
2916 ! |
2916 ! |
2917 |
2917 |
2918 readsField:instVarIndex |
2918 readsField:instVarIndex |
2932 Returns either nil, or a single symbol." |
2932 Returns either nil, or a single symbol." |
2933 |
2933 |
2934 |resources| |
2934 |resources| |
2935 |
2935 |
2936 (resources := self resources) notNil ifTrue:[ |
2936 (resources := self resources) notNil ifTrue:[ |
2937 resources keysAndValuesDo:[:key :val| |
2937 resources keysAndValuesDo:[:key :val| |
2938 ^ key |
2938 ^ key |
2939 ]. |
2939 ]. |
2940 ]. |
2940 ]. |
2941 ^ nil |
2941 ^ nil |
2942 ! |
2942 ! |
2943 |
2943 |
2944 resources |
2944 resources |
2948 self hasResource ifFalse:[^ nil]. |
2948 self hasResource ifFalse:[^ nil]. |
2949 annotations ifNil:[^ self parseResources]. |
2949 annotations ifNil:[^ self parseResources]. |
2950 |
2950 |
2951 resources := IdentityDictionary new. |
2951 resources := IdentityDictionary new. |
2952 self annotationsAt: #resource: orAt: #resource:value: do: |
2952 self annotationsAt: #resource: orAt: #resource:value: do: |
2953 [:annot| |
2953 [:annot| |
2954 resources at: annot type put: annot value ? true]. |
2954 resources at: annot type put: annot value ? true]. |
2955 ^resources |
2955 ^resources |
2956 |
2956 |
2957 "Modified: / 16-07-2010 / 11:49:27 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
2957 "Modified: / 16-07-2010 / 11:49:27 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
2958 ! |
2958 ! |
2959 |
2959 |
2985 sends:aSelectorSymbol |
2985 sends:aSelectorSymbol |
2986 "return true, if this method contains a message-send |
2986 "return true, if this method contains a message-send |
2987 with aSelectorSymbol as selector." |
2987 with aSelectorSymbol as selector." |
2988 |
2988 |
2989 (self referencesLiteral:aSelectorSymbol) ifTrue:[ |
2989 (self referencesLiteral:aSelectorSymbol) ifTrue:[ |
2990 ^ self messagesSent includesIdentical:aSelectorSymbol |
2990 ^ self messagesSent includesIdentical:aSelectorSymbol |
2991 ]. |
2991 ]. |
2992 ^ false |
2992 ^ false |
2993 ! |
2993 ! |
2994 |
2994 |
2995 sends:selectorSymbol1 or:selectorSymbol2 |
2995 sends:selectorSymbol1 or:selectorSymbol2 |
2997 to either selectorSymbol1 or selectorSymbol2." |
2997 to either selectorSymbol1 or selectorSymbol2." |
2998 |
2998 |
2999 |msgs| |
2999 |msgs| |
3000 |
3000 |
3001 ((self referencesLiteral:selectorSymbol1) or:[self referencesLiteral:selectorSymbol2]) ifTrue:[ |
3001 ((self referencesLiteral:selectorSymbol1) or:[self referencesLiteral:selectorSymbol2]) ifTrue:[ |
3002 msgs := self messagesSent. |
3002 msgs := self messagesSent. |
3003 ^ (msgs includesIdentical:selectorSymbol1) or:[msgs includesIdentical:selectorSymbol2] |
3003 ^ (msgs includesIdentical:selectorSymbol1) or:[msgs includesIdentical:selectorSymbol2] |
3004 ]. |
3004 ]. |
3005 ^ false |
3005 ^ false |
3006 ! |
3006 ! |
3007 |
3007 |
3008 shouldBeSkippedInDebuggersWalkBack |
3008 shouldBeSkippedInDebuggersWalkBack |
3049 who |
3049 who |
3050 "return the class and selector of where I am defined in; |
3050 "return the class and selector of where I am defined in; |
3051 nil is returned for unbound methods. |
3051 nil is returned for unbound methods. |
3052 |
3052 |
3053 ST/X special notice: |
3053 ST/X special notice: |
3054 returns an instance of MethodWhoInfo, which |
3054 returns an instance of MethodWhoInfo, which |
3055 responds to #methodClass and #methodSelector query messages. |
3055 responds to #methodClass and #methodSelector query messages. |
3056 For backward- (& ST-80) compatibility, the returned object also |
3056 For backward- (& ST-80) compatibility, the returned object also |
3057 responds to #at:1 and #at:2 messages. |
3057 responds to #at:1 and #at:2 messages. |
3058 |
3058 |
3059 Implementation notice: |
3059 Implementation notice: |
3060 Since there is no information of the containing class |
3060 Since there is no information of the containing class |
3061 in the method, we have to do a search here. |
3061 in the method, we have to do a search here. |
3062 |
3062 |
3063 Normally, this is not a problem, except when a method is |
3063 Normally, this is not a problem, except when a method is |
3064 accepted in the debugger or redefined from within a method |
3064 accepted in the debugger or redefined from within a method |
3065 (maybe done indirectly, if #doIt is done recursively) |
3065 (maybe done indirectly, if #doIt is done recursively) |
3066 - the information about which class the original method was |
3066 - the information about which class the original method was |
3067 defined in is lost in this case. |
3067 defined in is lost in this case. |
3068 |
3068 |
3069 Problem: |
3069 Problem: |
3070 this is heavily called for in the debugger to create |
3070 this is heavily called for in the debugger to create |
3071 a readable context walkback. For unbound methods, it is |
3071 a readable context walkback. For unbound methods, it is |
3072 slow, since the search (over all classes) will always fail. |
3072 slow, since the search (over all classes) will always fail. |
3073 |
3073 |
3074 Q: should we add a backref from the method to the class |
3074 Q: should we add a backref from the method to the class |
3075 and/or add a subclass of Method for unbound ones ? |
3075 and/or add a subclass of Method for unbound ones ? |
3076 Q2: if so, what about the bad guy then, who copies methods around to |
3076 Q2: if so, what about the bad guy then, who copies methods around to |
3077 other classes ?" |
3077 other classes ?" |
3078 |
3078 |
3079 |classes cls sel fn clsName checkBlock| |
3079 |classes cls sel fn clsName checkBlock| |
3080 |
3080 |
3081 mclass notNil ifTrue:[ |
3081 mclass notNil ifTrue:[ |
3082 sel := mclass selectorAtMethod:self. |
3082 sel := mclass selectorAtMethod:self. |
3083 sel notNil ifTrue:[ |
3083 sel notNil ifTrue:[ |
3084 ^ MethodWhoInfo class:mclass selector:sel |
3084 ^ MethodWhoInfo class:mclass selector:sel |
3085 ]. |
3085 ]. |
3086 "/ flush outdated mclass info |
3086 "/ flush outdated mclass info |
3087 mclass := nil. |
3087 mclass := nil. |
3088 ]. |
3088 ]. |
3089 |
3089 |
3090 checkBlock := [:cls | |
3090 checkBlock := [:cls | |
3091 |sel| |
3091 |sel| |
3092 |
3092 |
3093 sel := cls selectorAtMethod:self. |
3093 sel := cls selectorAtMethod:self. |
3094 sel notNil ifTrue:[ |
3094 sel notNil ifTrue:[ |
3095 LastWhoClass := cls theNonMetaclass name. |
3095 LastWhoClass := cls theNonMetaclass name. |
3096 mclass isNil ifTrue:[ |
3096 mclass isNil ifTrue:[ |
3097 mclass := cls |
3097 mclass := cls |
3098 ]. |
3098 ]. |
3099 ^ MethodWhoInfo class:cls selector:sel |
3099 ^ MethodWhoInfo class:cls selector:sel |
3100 ]. |
3100 ]. |
3101 ]. |
3101 ]. |
3102 |
3102 |
3103 " |
3103 " |
3104 speedup kludge: if my sourceFileName is valid, |
3104 speedup kludge: if my sourceFileName is valid, |
3105 extract the className from it and try that class first. |
3105 extract the className from it and try that class first. |
3106 " |
3106 " |
3107 (fn := self sourceFilename) notNil ifTrue:[ |
3107 (fn := self sourceFilename) notNil ifTrue:[ |
3108 clsName := fn asFilename nameWithoutSuffix. |
3108 clsName := fn asFilename nameWithoutSuffix. |
3109 clsName := clsName asSymbolIfInterned. |
3109 clsName := clsName asSymbolIfInterned. |
3110 clsName notNil ifTrue:[ |
3110 clsName notNil ifTrue:[ |
3111 cls := Smalltalk at:clsName ifAbsent:nil. |
3111 cls := Smalltalk at:clsName ifAbsent:nil. |
3112 cls notNil ifTrue:[ |
3112 cls notNil ifTrue:[ |
3113 checkBlock value:cls theNonMetaclass. |
3113 checkBlock value:cls theNonMetaclass. |
3114 checkBlock value:cls theMetaclass. |
3114 checkBlock value:cls theMetaclass. |
3115 ] |
3115 ] |
3116 ]. |
3116 ]. |
3117 ]. |
3117 ]. |
3118 |
3118 |
3119 " |
3119 " |
3120 then, look in the class we found something the last time |
3120 then, look in the class we found something the last time |
3121 this may often give a hit, when asking who repeatingly for |
3121 this may often give a hit, when asking who repeatingly for |
3122 a context chain. (keep last by its name, to not keep classes from |
3122 a context chain. (keep last by its name, to not keep classes from |
3123 being garbage collected) |
3123 being garbage collected) |
3124 " |
3124 " |
3125 LastWhoClass notNil ifTrue:[ |
3125 LastWhoClass notNil ifTrue:[ |
3126 cls := Smalltalk at:LastWhoClass ifAbsent:nil. |
3126 cls := Smalltalk at:LastWhoClass ifAbsent:nil. |
3127 cls notNil ifTrue:[ |
3127 cls notNil ifTrue:[ |
3128 checkBlock value:cls theNonMetaclass. |
3128 checkBlock value:cls theNonMetaclass. |
3129 checkBlock value:cls theMetaclass. |
3129 checkBlock value:cls theMetaclass. |
3130 ] |
3130 ] |
3131 ]. |
3131 ]. |
3132 |
3132 |
3133 " |
3133 " |
3134 first, limit the search to global classes only - |
3134 first, limit the search to global classes only - |
3135 since probability is high, that the receiver is found in there ... |
3135 since probability is high, that the receiver is found in there ... |
3137 classes := Smalltalk allClasses. |
3137 classes := Smalltalk allClasses. |
3138 " |
3138 " |
3139 instance methods are usually more common - search those first |
3139 instance methods are usually more common - search those first |
3140 " |
3140 " |
3141 classes do:[:cls | |
3141 classes do:[:cls | |
3142 checkBlock value:cls theNonMetaclass. |
3142 checkBlock value:cls theNonMetaclass. |
3143 checkBlock value:cls theMetaclass. |
3143 checkBlock value:cls theMetaclass. |
3144 ]. |
3144 ]. |
3145 |
3145 |
3146 LastWhoClass := nil. |
3146 LastWhoClass := nil. |
3147 "/ " |
3147 "/ " |
3148 "/ mhmh - must be a method of some anonymous class (i.e. one not |
3148 "/ mhmh - must be a method of some anonymous class (i.e. one not |
3168 "untypical situation: an anonymous class" |
3168 "untypical situation: an anonymous class" |
3169 " |
3169 " |
3170 |m cls| |
3170 |m cls| |
3171 |
3171 |
3172 Object |
3172 Object |
3173 subclass:#FunnyClass |
3173 subclass:#FunnyClass |
3174 instanceVariableNames:'foo' |
3174 instanceVariableNames:'foo' |
3175 classVariableNames:'' |
3175 classVariableNames:'' |
3176 poolDictionaries:'' |
3176 poolDictionaries:'' |
3177 category:'testing'. |
3177 category:'testing'. |
3178 cls := Smalltalk at:#FunnyClass. |
3178 cls := Smalltalk at:#FunnyClass. |
3179 Smalltalk removeClass:cls. |
3179 Smalltalk removeClass:cls. |
3180 |
3180 |
3181 cls compile:'testMethod1:arg foo:=arg'. |
3181 cls compile:'testMethod1:arg foo:=arg'. |
3182 cls compile:'testMethod2 ^ foo'. |
3182 cls compile:'testMethod2 ^ foo'. |
3191 wrapper |
3191 wrapper |
3192 "only for wrapped methods: return the wrapper. |
3192 "only for wrapped methods: return the wrapper. |
3193 Thats the WrapperMethod which contains myself." |
3193 Thats the WrapperMethod which contains myself." |
3194 |
3194 |
3195 WrappedMethod allInstancesDo:[:m | |
3195 WrappedMethod allInstancesDo:[:m | |
3196 m originalMethod == self ifTrue:[^ m]. |
3196 m originalMethod == self ifTrue:[^ m]. |
3197 ]. |
3197 ]. |
3198 ^ nil |
3198 ^ nil |
3199 ! |
3199 ! |
3200 |
3200 |
3201 writesField:instVarIndex |
3201 writesField:instVarIndex |
3260 |
3260 |
3261 trapMethodForNumArgs:numArgs |
3261 trapMethodForNumArgs:numArgs |
3262 |trapSel| |
3262 |trapSel| |
3263 |
3263 |
3264 trapSel := #( |
3264 trapSel := #( |
3265 #'invalidCodeObject' |
3265 #'invalidCodeObject' |
3266 #'invalidCodeObjectWith:' |
3266 #'invalidCodeObjectWith:' |
3267 #'invalidCodeObjectWith:with:' |
3267 #'invalidCodeObjectWith:with:' |
3268 #'invalidCodeObjectWith:with:with:' |
3268 #'invalidCodeObjectWith:with:with:' |
3269 #'invalidCodeObjectWith:with:with:with:' |
3269 #'invalidCodeObjectWith:with:with:with:' |
3270 #'invalidCodeObjectWith:with:with:with:with:' |
3270 #'invalidCodeObjectWith:with:with:with:with:' |
3271 #'invalidCodeObjectWith:with:with:with:with:with:' |
3271 #'invalidCodeObjectWith:with:with:with:with:with:' |
3272 #'invalidCodeObjectWith:with:with:with:with:with:with:' |
3272 #'invalidCodeObjectWith:with:with:with:with:with:with:' |
3273 #'invalidCodeObjectWith:with:with:with:with:with:with:with:' |
3273 #'invalidCodeObjectWith:with:with:with:with:with:with:with:' |
3274 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:' |
3274 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:' |
3275 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:' |
3275 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:' |
3276 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:' |
3276 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:' |
3277 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:' |
3277 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:' |
3278 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:with:' |
3278 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:with:' |
3279 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:with:with:' |
3279 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:with:with:' |
3280 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:with:with:with:' |
3280 #'invalidCodeObjectWith:with:with:with:with:with:with:with:with:with:with:with:with:with:with:' |
3281 ) at:(numArgs + 1). |
3281 ) at:(numArgs + 1). |
3282 |
3282 |
3283 ^ Method compiledMethodAt:trapSel. |
3283 ^ Method compiledMethodAt:trapSel. |
3284 |
3284 |
3285 "Created: 4.11.1996 / 21:58:58 / cg" |
3285 "Created: 4.11.1996 / 21:58:58 / cg" |
3286 "Modified: 4.11.1996 / 23:18:05 / cg" |
3286 "Modified: 4.11.1996 / 23:18:05 / cg" |
3293 In earlier times, Method>>who returned an array filled |
3293 In earlier times, Method>>who returned an array filled |
3294 with the methods class and selector. |
3294 with the methods class and selector. |
3295 This was done, since a smalltalk method cannot return multiple |
3295 This was done, since a smalltalk method cannot return multiple |
3296 values, but 2 values had to be returned from that method. |
3296 values, but 2 values had to be returned from that method. |
3297 Thus, the who-interface was used as: |
3297 Thus, the who-interface was used as: |
3298 info := <someMethod> who. |
3298 info := <someMethod> who. |
3299 class := info at:1. |
3299 class := info at:1. |
3300 sel := info at:2. |
3300 sel := info at:2. |
3301 |
3301 |
3302 Sure, this is ugly coding style, and the system has been changed to return |
3302 Sure, this is ugly coding style, and the system has been changed to return |
3303 an object (an instance of MethodWhoInfo) which responds to the two |
3303 an object (an instance of MethodWhoInfo) which responds to the two |
3304 messages: #methodClass and #methodSelector. |
3304 messages: #methodClass and #methodSelector. |
3305 This allows to write things much more intuitive: |
3305 This allows to write things much more intuitive: |
3306 info := <someMethod> who. |
3306 info := <someMethod> who. |
3307 class := info methodClass. |
3307 class := info methodClass. |
3308 sel := info methodSelector. |
3308 sel := info methodSelector. |
3309 |
3309 |
3310 However, to be backward compatible, the returned object still responds to |
3310 However, to be backward compatible, the returned object still responds to |
3311 the #at: message, but only allows inices of 1 and 2 to be used. |
3311 the #at: message, but only allows inices of 1 and 2 to be used. |
3312 |
3312 |
3313 The MethodWhoInfo class is private to Method - its not visible to other |
3313 The MethodWhoInfo class is private to Method - its not visible to other |
3314 classes. |
3314 classes. |
3315 |
3315 |
3316 [author:] |
3316 [author:] |
3317 Claus Gittinger |
3317 Claus Gittinger |
3318 |
3318 |
3319 [see also:] |
3319 [see also:] |
3320 Method |
3320 Method |
3321 " |
3321 " |
3322 ! ! |
3322 ! ! |
3323 |
3323 |
3324 !Method::MethodWhoInfo class methodsFor:'instance creation'! |
3324 !Method::MethodWhoInfo class methodsFor:'instance creation'! |
3325 |
3325 |
3364 |
3364 |
3365 at:index |
3365 at:index |
3366 "simulate the old behavior (when Method>>who returned an array)" |
3366 "simulate the old behavior (when Method>>who returned an array)" |
3367 |
3367 |
3368 index == 1 ifTrue:[ |
3368 index == 1 ifTrue:[ |
3369 ^ myClass |
3369 ^ myClass |
3370 ]. |
3370 ]. |
3371 index == 2 ifTrue:[ |
3371 index == 2 ifTrue:[ |
3372 ^ mySelector |
3372 ^ mySelector |
3373 ]. |
3373 ]. |
3374 |
3374 |
3375 "/ sigh - full compatibility ? |
3375 "/ sigh - full compatibility ? |
3376 ^ self indexNotIntegerOrOutOfBounds:index |
3376 ^ self indexNotIntegerOrOutOfBounds:index |
3377 ! ! |
3377 ! ! |
3386 ! ! |
3386 ! ! |
3387 |
3387 |
3388 !Method class methodsFor:'documentation'! |
3388 !Method class methodsFor:'documentation'! |
3389 |
3389 |
3390 version_CVS |
3390 version_CVS |
3391 ^ '$Header: /cvs/stx/stx/libbasic/Method.st,v 1.358 2011-06-28 18:09:51 vrany Exp $' |
3391 ^ '$Header: /cvs/stx/stx/libbasic/Method.st,v 1.359 2011-06-29 19:18:20 cg Exp $' |
3392 ! |
3392 ! |
3393 |
3393 |
3394 version_SVN |
3394 version_SVN |
3395 ^ ' Id: Method.st 10648 2011-06-23 15:55:10Z vranyj1 ' |
3395 ^ '§ Id: Method.st 10648 2011-06-23 15:55:10Z vranyj1 §' |
3396 ! ! |
3396 ! ! |
3397 |
3397 |
3398 Method initialize! |
3398 Method initialize! |