resin 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. data/amber/bin/amberc +10 -350
  2. data/amber/js/Benchfib.deploy.js +80 -89
  3. data/amber/js/Benchfib.js +80 -89
  4. data/amber/js/Canvas.deploy.js +558 -545
  5. data/amber/js/Canvas.js +563 -545
  6. data/amber/js/Compiler-AST.deploy.js +431 -243
  7. data/amber/js/Compiler-AST.js +487 -244
  8. data/amber/js/Compiler-Core.deploy.js +201 -1045
  9. data/amber/js/Compiler-Core.js +208 -1207
  10. data/amber/js/Compiler-Exceptions.deploy.js +37 -18
  11. data/amber/js/Compiler-Exceptions.js +42 -18
  12. data/amber/js/Compiler-IR.deploy.js +1071 -774
  13. data/amber/js/Compiler-IR.js +1194 -848
  14. data/amber/js/Compiler-Inlining.deploy.js +395 -373
  15. data/amber/js/Compiler-Inlining.js +395 -373
  16. data/amber/js/Compiler-Interpreter.deploy.js +1202 -0
  17. data/amber/js/Compiler-Interpreter.js +1631 -0
  18. data/amber/js/Compiler-Semantic.deploy.js +695 -600
  19. data/amber/js/Compiler-Semantic.js +721 -611
  20. data/amber/js/Compiler-Tests.deploy.js +699 -376
  21. data/amber/js/Compiler-Tests.js +834 -381
  22. data/amber/js/Compiler.deploy.js +8563 -1805
  23. data/amber/js/Compiler.js +11476 -2633
  24. data/amber/js/Examples.deploy.js +29 -29
  25. data/amber/js/Examples.js +29 -29
  26. data/amber/js/IDE.deploy.js +3292 -2649
  27. data/amber/js/IDE.js +3318 -2710
  28. data/amber/js/Importer-Exporter.deploy.js +393 -349
  29. data/amber/js/Importer-Exporter.js +398 -354
  30. data/amber/js/Kernel-Announcements.deploy.js +53 -44
  31. data/amber/js/Kernel-Announcements.js +55 -44
  32. data/amber/js/Kernel-Classes.deploy.js +566 -368
  33. data/amber/js/Kernel-Classes.js +660 -402
  34. data/amber/js/Kernel-Collections.deploy.js +1149 -1098
  35. data/amber/js/Kernel-Collections.js +1183 -1116
  36. data/amber/js/Kernel-Exceptions.deploy.js +173 -75
  37. data/amber/js/Kernel-Exceptions.js +215 -77
  38. data/amber/js/Kernel-Methods.deploy.js +530 -313
  39. data/amber/js/Kernel-Methods.js +632 -338
  40. data/amber/js/Kernel-Objects.deploy.js +1734 -1577
  41. data/amber/js/Kernel-Objects.js +1867 -1654
  42. data/amber/js/Kernel-Tests.deploy.js +1416 -973
  43. data/amber/js/Kernel-Tests.js +1495 -981
  44. data/amber/js/Kernel-Transcript.deploy.js +23 -24
  45. data/amber/js/Kernel-Transcript.js +25 -26
  46. data/amber/js/SUnit-Tests.deploy.js +402 -0
  47. data/amber/js/SUnit-Tests.js +518 -0
  48. data/amber/js/SUnit.deploy.js +535 -237
  49. data/amber/js/SUnit.js +634 -246
  50. data/amber/js/amber.js +90 -53
  51. data/amber/js/boot.js +441 -255
  52. data/amber/js/init.js +1 -3
  53. data/amber/js/lib/CodeMirror/codemirror.css +3 -0
  54. data/amber/js/lib/CodeMirror/codemirror.js +104 -55
  55. data/amber/js/lib/peg-0.7.0.min.js +9 -0
  56. data/amber/js/parser.js +1504 -802
  57. data/amber/js/parser.pegjs +170 -165
  58. data/amber/st/Canvas.st +6 -0
  59. data/amber/st/Compiler-AST.st +54 -3
  60. data/amber/st/Compiler-Core.st +6 -551
  61. data/amber/st/Compiler-Exceptions.st +4 -0
  62. data/amber/st/Compiler-IR.st +205 -87
  63. data/amber/st/Compiler-Interpreter.st +597 -0
  64. data/amber/st/Compiler-Semantic.st +46 -21
  65. data/amber/st/Compiler-Tests.st +254 -7
  66. data/amber/st/Compiler.st +3172 -1541
  67. data/amber/st/IDE.st +57 -93
  68. data/amber/st/Importer-Exporter.st +4 -7
  69. data/amber/st/Kernel-Announcements.st +8 -0
  70. data/amber/st/Kernel-Classes.st +149 -40
  71. data/amber/st/Kernel-Collections.st +43 -32
  72. data/amber/st/Kernel-Exceptions.st +70 -1
  73. data/amber/st/Kernel-Methods.st +165 -27
  74. data/amber/st/Kernel-Objects.st +215 -140
  75. data/amber/st/Kernel-Tests.st +195 -10
  76. data/amber/st/Kernel-Transcript.st +1 -3
  77. data/amber/st/SUnit-Tests.st +186 -0
  78. data/amber/st/SUnit.st +186 -14
  79. data/bin/resin +6 -0
  80. data/lib/resin/cli.rb +19 -0
  81. metadata +41 -25
  82. data/amber/js/lib/peg-0.6.2.min.js +0 -2
  83. data/bin/resin-compile +0 -6
  84. data/bin/runresin +0 -12
@@ -156,10 +156,10 @@ ErrorHandler subclass: #DebugErrorHandler
156
156
  !DebugErrorHandler methodsFor: 'error handling'!
157
157
 
158
158
  handleError: anError
159
- [Debugger new
159
+ [ Debugger new
160
160
  error: anError;
161
- open] on: Error do: [:error |
162
- ErrorHandler new handleError: error]
161
+ open ] on: Error do: [ :error |
162
+ ErrorHandler new handleError: error ]
163
163
  ! !
164
164
 
165
165
  !DebugErrorHandler class methodsFor: 'initialization'!
@@ -208,22 +208,6 @@ selection
208
208
  ^editor getSelection
209
209
  !
210
210
 
211
- selectionEnd
212
- ^textarea element selectionEnd
213
- !
214
-
215
- selectionEnd: anInteger
216
- textarea element selectionEnd: anInteger
217
- !
218
-
219
- selectionStart
220
- ^textarea element selectionStart
221
- !
222
-
223
- selectionStart: anInteger
224
- textarea element selectionStart: anInteger
225
- !
226
-
227
211
  setEditorOn: aTextarea
228
212
  <self['@editor'] = CodeMirror.fromTextArea(aTextarea, {
229
213
  theme: 'amber',
@@ -296,13 +280,20 @@ inspectIt
296
280
  !
297
281
 
298
282
  print: aString
299
- | start stop |
283
+ | start stop currentLine |
284
+ currentLine := (editor getCursor: false) line.
300
285
  start := HashedCollection new.
301
- stop := HashedCollection new.
302
- start at: 'line' put: (editor getCursor: false) line.
286
+ start at: 'line' put: currentLine.
303
287
  start at: 'ch' put: (editor getCursor: false) ch.
304
- stop at: 'line' put: (start at: 'line').
288
+ (editor getSelection) ifEmpty: [
289
+ "select current line if selection is empty"
290
+ start at: 'ch' put: (editor getLine: currentLine) size.
291
+ editor setSelection: #{'line' -> currentLine. 'ch' -> 0} end: start.
292
+ ].
293
+ stop := HashedCollection new.
294
+ stop at: 'line' put: currentLine.
305
295
  stop at: 'ch' put: ((start at: 'ch') + aString size + 2).
296
+
306
297
  editor replaceSelection: (editor getSelection, ' ', aString, ' ').
307
298
  editor setCursor: (editor getCursor: true).
308
299
  editor setSelection: stop end: start
@@ -790,15 +781,15 @@ cancelChanges
790
781
 
791
782
  commitPackage
792
783
  selectedPackage ifNotNil: [ |package|
793
- package := Package named: selectedPackage.
794
- { Exporter -> (package commitPathJs, '/', selectedPackage, '.js').
795
- StrippedExporter -> (package commitPathJs, '/', selectedPackage, '.deploy.js').
796
- ChunkExporter -> (package commitPathSt, '/', selectedPackage, '.st') }
797
-
798
- do: [:commitStrategy| |fileContents|
799
- fileContents := (commitStrategy key new exportPackage: selectedPackage).
800
- self ajaxPutAt: commitStrategy value data: fileContents]
801
- ]
784
+ package := Package named: selectedPackage.
785
+ { Exporter -> (package commitPathJs, '/', selectedPackage, '.js').
786
+ StrippedExporter -> (package commitPathJs, '/', selectedPackage, '.deploy.js').
787
+ ChunkExporter -> (package commitPathSt, '/', selectedPackage, '.st')
788
+ } do: [:commitStrategy| |fileContents|
789
+ fileContents := (commitStrategy key new exportPackage: selectedPackage).
790
+ self ajaxPutAt: commitStrategy value data: fileContents
791
+ ]
792
+ ]
802
793
  !
803
794
 
804
795
  compile
@@ -839,7 +830,7 @@ compileMethodDefinition
839
830
  compileMethodDefinitionFor: aClass
840
831
  | compiler method source node |
841
832
  source := sourceArea val.
842
- selectedProtocol ifNil: [selectedProtocol := selectedMethod category].
833
+ selectedProtocol ifNil: [ selectedProtocol := selectedMethod category ].
843
834
  compiler := Compiler new.
844
835
  compiler source: source.
845
836
  node := compiler parse: source.
@@ -847,15 +838,13 @@ compileMethodDefinitionFor: aClass
847
838
  ^window alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].
848
839
  compiler currentClass: aClass.
849
840
  method := compiler eval: (compiler compileNode: node).
850
- method category: selectedProtocol.
851
841
  compiler unknownVariables do: [:each |
852
842
  "Do not try to redeclare javascript's objects"
853
843
  (window at: each) ifNil: [
854
844
  (window confirm: 'Declare ''', each, ''' as instance variable?') ifTrue: [
855
845
  self addInstanceVariableNamed: each toClass: aClass.
856
846
  ^self compileMethodDefinitionFor: aClass]]].
857
- aClass addCompiledMethod: method.
858
- compiler setupClass: aClass.
847
+ ClassBuilder new installMethod: method forClass: aClass category: selectedProtocol.
859
848
  self updateMethodsList.
860
849
  self selectMethod: method
861
850
  !
@@ -1041,12 +1030,12 @@ initialize
1041
1030
 
1042
1031
  !Browser methodsFor: 'network'!
1043
1032
 
1044
- ajaxPutAt: anURL data: aString
1045
- jQuery
1046
- ajax: anURL options: #{ 'type' -> 'PUT'.
1033
+ ajaxPutAt: aURL data: aString
1034
+ jQuery
1035
+ ajax: aURL options: #{ 'type' -> 'PUT'.
1047
1036
  'data' -> aString.
1048
1037
  'contentType' -> 'text/plain;charset=UTF-8'.
1049
- 'error' -> [window alert: 'PUT request failed at: ', anURL] }
1038
+ 'error' -> [:xhr | window alert: 'Commiting ' , aURL , ' failed with reason: "' , (xhr responseText) , '"'] }
1050
1039
  ! !
1051
1040
 
1052
1041
  !Browser methodsFor: 'rendering'!
@@ -1285,16 +1274,6 @@ updateTabsList
1285
1274
  onClick: [self selectTab: #comment]]
1286
1275
  ! !
1287
1276
 
1288
- !Browser class methodsFor: 'accessing'!
1289
-
1290
- commitPathJs
1291
- ^'js'
1292
- !
1293
-
1294
- commitPathSt
1295
- ^'st'
1296
- ! !
1297
-
1298
1277
  !Browser class methodsFor: 'convenience'!
1299
1278
 
1300
1279
  open
@@ -1314,10 +1293,17 @@ TabWidget subclass: #Debugger
1314
1293
 
1315
1294
  !Debugger methodsFor: 'accessing'!
1316
1295
 
1317
- arguments
1318
- ^self method
1319
- ifNil: [selectedContext temps collect: [:each | nil]]
1320
- ifNotNil: [self method arguments]
1296
+ allVariables
1297
+ | all |
1298
+ all := Dictionary new.
1299
+
1300
+ self receiver class allInstanceVariableNames do: [:each |
1301
+ all at: each put: (self receiver instVarAt: each) ].
1302
+
1303
+ selectedContext locals keysAndValuesDo: [ :key :value |
1304
+ all at: key put: value ].
1305
+
1306
+ ^ all
1321
1307
  !
1322
1308
 
1323
1309
  error
@@ -1333,7 +1319,7 @@ label
1333
1319
  !
1334
1320
 
1335
1321
  method
1336
- ^selectedContext receiver class methodAt: selectedContext selector
1322
+ ^selectedContext method
1337
1323
  !
1338
1324
 
1339
1325
  receiver
@@ -1377,6 +1363,7 @@ selectContext: aContext
1377
1363
  !
1378
1364
 
1379
1365
  selectVariable: anObject named: aString
1366
+
1380
1367
  selectedVariable := anObject.
1381
1368
  selectedVariableName := aString.
1382
1369
  inspector contents: [:html | html with: anObject printString].
@@ -1405,7 +1392,7 @@ renderBottomPanelOn: html
1405
1392
  !
1406
1393
 
1407
1394
  renderBoxOn: html
1408
- self
1395
+ self
1409
1396
  renderTopPanelOn: html;
1410
1397
  renderBottomPanelOn: html
1411
1398
  !
@@ -1448,7 +1435,7 @@ renderContext: aContext on: html
1448
1435
  li
1449
1436
  with: aContext asString;
1450
1437
  onClick: [self selectContext: aContext].
1451
- aContext home ifNotNil: [self renderContext: aContext home on: html]
1438
+ aContext outerContext ifNotNil: [self renderContext: aContext outerContext on: html]
1452
1439
  !
1453
1440
 
1454
1441
  renderTopPanelOn: html
@@ -1498,27 +1485,22 @@ updateStatus
1498
1485
  !
1499
1486
 
1500
1487
  updateVariablesList
1501
- ul2 contents: [:html | | li |
1488
+ ul2 contents: [ :html | | li |
1502
1489
  li := html li
1503
1490
  with: 'self';
1504
- onClick: [self selectVariable: self receiver named: 'self'].
1505
- selectedVariableName = 'self' ifTrue: [
1506
- li class: 'selected'].
1507
- self arguments withIndexDo: [:each :index | | param |
1508
- param := selectedContext temps at: index.
1491
+ onClick: [ self selectVariable: self receiver named: 'self' ].
1492
+ selectedVariableName = 'self' ifTrue: [ li class: 'selected' ].
1493
+
1494
+ self allVariables keysAndValuesDo: [:key :value |
1509
1495
  li := html li
1510
- with: each;
1511
- onClick: [self selectVariable: param named: each].
1512
- selectedVariableName = each ifTrue: [
1513
- li class: 'selected']].
1514
- self receiver class allInstanceVariableNames do: [:each | | ivar |
1515
- ivar := self receiver instVarAt: each.
1516
- li := html li
1517
- with: each;
1518
- onClick: [self selectVariable: ivar named: each].
1519
- selectedVariableName = each ifTrue: [
1520
- li class: 'selected']]].
1521
- selectedVariable ifNil: [inspectButton at: 'disabled' put: true] ifNotNil: [inspectButton removeAt: 'disabled']
1496
+ with: key;
1497
+ onClick: [ self selectVariable: value named: key ].
1498
+ selectedVariableName = key ifTrue: [
1499
+ li class: 'selected' ] ] ].
1500
+
1501
+ selectedVariable
1502
+ ifNil: [ inspectButton at: 'disabled' put: true ]
1503
+ ifNotNil: [ inspectButton removeAt: 'disabled' ]
1522
1504
  ! !
1523
1505
 
1524
1506
  TabWidget subclass: #IDETranscript
@@ -2388,24 +2370,6 @@ inspectOn: anInspector
2388
2370
  setVariables: variables
2389
2371
  ! !
2390
2372
 
2391
- !Date methodsFor: '*IDE'!
2392
-
2393
- inspectOn: anInspector
2394
- | variables |
2395
- variables := Dictionary new.
2396
- variables at: '#self' put: self.
2397
- variables at: '#year' put: self year.
2398
- variables at: '#month' put: self month.
2399
- variables at: '#day' put: self day.
2400
- variables at: '#hours' put: self hours.
2401
- variables at: '#minutes' put: self minutes.
2402
- variables at: '#seconds' put: self seconds.
2403
- variables at: '#milliseconds' put: self milliseconds.
2404
- anInspector
2405
- setLabel: self printString;
2406
- setVariables: variables
2407
- ! !
2408
-
2409
2373
  !MethodContext methodsFor: '*IDE'!
2410
2374
 
2411
2375
  inspectOn: anInspector
@@ -345,16 +345,13 @@ Object subclass: #PackageLoader
345
345
  instanceVariableNames: ''
346
346
  package: 'Importer-Exporter'!
347
347
 
348
- !PackageLoader methodsFor: 'not yet classified'!
348
+ !PackageLoader methodsFor: 'laoding'!
349
349
 
350
350
  initializePackageNamed: packageName prefix: aString
351
351
 
352
- (Package named: packageName) classes do: [ :each |
353
- <smalltalk.init(each)>.
354
- each initialize. ].
355
-
356
- (Package named: packageName)
357
- commitPathJs: '/', aString, '/js';
352
+ (Package named: packageName)
353
+ setupClasses;
354
+ commitPathJs: '/', aString, '/js';
358
355
  commitPathSt: '/', aString, '/st'
359
356
  !
360
357
 
@@ -2,6 +2,9 @@ Smalltalk current createPackage: 'Kernel-Announcements' properties: #{}!
2
2
  Object subclass: #AnnouncementSubscription
3
3
  instanceVariableNames: 'block announcementClass'
4
4
  package: 'Kernel-Announcements'!
5
+ !AnnouncementSubscription commentStamp!
6
+ The subscription is a single entry in a subscription registry of an `Announcer`.
7
+ Several subscriptions by the same object is possible.!
5
8
 
6
9
  !AnnouncementSubscription methodsFor: 'accessing'!
7
10
 
@@ -35,6 +38,11 @@ handlesAnnouncement: anAnnouncement
35
38
  Object subclass: #Announcer
36
39
  instanceVariableNames: 'registry subscriptions'
37
40
  package: 'Kernel-Announcements'!
41
+ !Announcer commentStamp!
42
+ The code is based on the announcements as [described by Vassili Bykov](http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?searchCategory=Announcements%20Framework).
43
+ The Announcer holds annoncement subscriptions (`AnnouncementSubscription`) in a private registry.
44
+
45
+ Use `#on:do:` to register subscriptions.!
38
46
 
39
47
  !Announcer methodsFor: 'announcing'!
40
48
 
@@ -68,13 +68,29 @@ instanceVariableNames
68
68
  <return self.iVarNames>
69
69
  !
70
70
 
71
+ lookupSelector: selector
72
+ "Look up the given selector in my methodDictionary.
73
+ Return the corresponding method if found.
74
+ Otherwise chase the superclass chain and try again.
75
+ Return nil if no method is found."
76
+
77
+ | lookupClass |
78
+
79
+ lookupClass := self.
80
+ [ lookupClass = nil ] whileFalse: [
81
+ (lookupClass includesSelector: selector)
82
+ ifTrue: [ ^ lookupClass methodAt: selector ].
83
+ lookupClass := lookupClass superclass ].
84
+ ^ nil
85
+ !
86
+
71
87
  methodAt: aSymbol
72
- <return smalltalk.methods(self)[aSymbol._asString()]>
88
+ ^ self methodDictionary at: aSymbol asString
73
89
  !
74
90
 
75
91
  methodDictionary
76
92
  <var dict = smalltalk.HashedCollection._new();
77
- var methods = self.fn.prototype.methods;
93
+ var methods = self.methods;
78
94
  for(var i in methods) {
79
95
  if(methods[i].selector) {
80
96
  dict._at_put_(methods[i].selector, methods[i]);
@@ -158,7 +174,7 @@ withAllSubclasses
158
174
  !Behavior methodsFor: 'compiling'!
159
175
 
160
176
  addCompiledMethod: aMethod
161
- <smalltalk.addMethod(aMethod.selector._asSelector(), aMethod, self)>.
177
+ self basicAddCompiledMethod: aMethod.
162
178
 
163
179
  SystemAnnouncer current
164
180
  announce: (MethodAdded new
@@ -179,10 +195,7 @@ compile: aString category: anotherString
179
195
  !
180
196
 
181
197
  removeCompiledMethod: aMethod
182
- <
183
- smalltalk.removeMethod(aMethod)
184
- smalltalk.init(self);
185
- >.
198
+ self basicRemoveCompiledMethod: aMethod.
186
199
 
187
200
  SystemAnnouncer current
188
201
  announce: (MethodRemoved new
@@ -201,6 +214,19 @@ new
201
214
  ^self basicNew initialize
202
215
  ! !
203
216
 
217
+ !Behavior methodsFor: 'private'!
218
+
219
+ basicAddCompiledMethod: aMethod
220
+ <smalltalk.addMethod(aMethod.selector._asSelector(), aMethod, self)>
221
+ !
222
+
223
+ basicRemoveCompiledMethod: aMethod
224
+ <
225
+ smalltalk.removeMethod(aMethod)
226
+ smalltalk.init(self);
227
+ >
228
+ ! !
229
+
204
230
  !Behavior methodsFor: 'testing'!
205
231
 
206
232
  canUnderstand: aSelector
@@ -208,6 +234,10 @@ canUnderstand: aSelector
208
234
  self superclass notNil and: [self superclass canUnderstand: aSelector]]
209
235
  !
210
236
 
237
+ includesSelector: aSymbol
238
+ ^ self methodDictionary includesKey: aSymbol asString
239
+ !
240
+
211
241
  inheritsFrom: aClass
212
242
  ^aClass allSubclasses includes: self
213
243
  ! !
@@ -364,26 +394,27 @@ ClassBuilder is responsible for compiling new classes or modifying existing clas
364
394
 
365
395
  Rather than using ClassBuilder directly to compile a class, use `Class >> subclass:instanceVariableNames:package:`.!
366
396
 
367
- !ClassBuilder methodsFor: 'class creation'!
397
+ !ClassBuilder methodsFor: 'api'!
368
398
 
369
399
  class: aClass instanceVariableNames: aString
370
- aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
371
- aClass basicAt: 'iVarNames' put: (self instanceVariableNamesFor: aString).
400
+ self basicClass: aClass instanceVariableNames: aString.
401
+ self setupClass: aClass.
372
402
 
373
403
  SystemAnnouncer current
374
404
  announce: (ClassDefinitionChanged new
375
405
  theClass: aClass;
376
- yourself).
377
-
378
- self setupClass: aClass
406
+ yourself)
407
+ !
408
+
409
+ installMethod: aCompiledMethod forClass: aBehavior category: aString
410
+ aCompiledMethod category: aString.
411
+ aBehavior addCompiledMethod: aCompiledMethod.
412
+ self setupClass: aBehavior.
413
+ ^aCompiledMethod
379
414
  !
380
415
 
381
416
  renameClass: aClass to: aString
382
- <
383
- smalltalk[aString] = aClass;
384
- delete smalltalk[aClass.className];
385
- aClass.className = aString;
386
- >.
417
+ self basicRenameClass: aClass to: aString.
387
418
 
388
419
  SystemAnnouncer current
389
420
  announce: (ClassRenamed new
@@ -391,6 +422,10 @@ renameClass: aClass to: aString
391
422
  yourself)
392
423
  !
393
424
 
425
+ setupClass: aClass
426
+ <smalltalk.init(aClass);>
427
+ !
428
+
394
429
  superclass: aClass subclass: aString
395
430
  ^self superclass: aClass subclass: aString instanceVariableNames: '' package: nil
396
431
  !
@@ -413,14 +448,49 @@ superclass: aClass subclass: aString instanceVariableNames: aString2 package: aS
413
448
 
414
449
  !ClassBuilder methodsFor: 'private'!
415
450
 
416
- addSubclassOf: aClass named: aString instanceVariableNames: aCollection
417
- <smalltalk.addClass(aString, aClass, aCollection);
418
- return smalltalk[aString]>
451
+ addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
452
+
453
+ (Smalltalk current at: aString) ifNotNil: [
454
+ ^ self
455
+ migrateClassNamed: aString
456
+ superclass: aClass
457
+ instanceVariableNames: aCollection
458
+ package: packageName ].
459
+
460
+ ^ self
461
+ basicAddSubclassOf: aClass
462
+ named: aString
463
+ instanceVariableNames: aCollection
464
+ package: packageName
419
465
  !
420
466
 
421
- addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
422
- <smalltalk.addClass(aString, aClass, aCollection, packageName);
423
- return smalltalk[aString]>
467
+ basicAddSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
468
+ <
469
+ smalltalk.addClass(aString, aClass, aCollection, packageName);
470
+ return smalltalk[aString]
471
+ >
472
+ !
473
+
474
+ basicClass: aClass instanceVariableNames: aString
475
+ self basicClass: aClass instanceVariables: (self instanceVariableNamesFor: aString)
476
+ !
477
+
478
+ basicClass: aClass instanceVariables: aCollection
479
+
480
+ aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
481
+ aClass basicAt: 'iVarNames' put: aCollection
482
+ !
483
+
484
+ basicRemoveClass: aClass
485
+ <smalltalk.removeClass(aClass)>
486
+ !
487
+
488
+ basicRenameClass: aClass to: aString
489
+ <
490
+ smalltalk[aString] = aClass;
491
+ delete smalltalk[aClass.className];
492
+ aClass.className = aString;
493
+ >
424
494
  !
425
495
 
426
496
  copyClass: aClass named: aString
@@ -432,28 +502,69 @@ copyClass: aClass named: aString
432
502
  instanceVariableNames: aClass instanceVariableNames
433
503
  package: aClass package name.
434
504
 
435
- self setupClass: newClass.
505
+ self copyClass: aClass to: newClass.
506
+
507
+ ^newClass
508
+ !
436
509
 
437
- aClass methodDictionary values do: [:each |
438
- Compiler new install: each source forClass: newClass category: each category].
510
+ copyClass: aClass to: anotherClass
439
511
 
440
- aClass class methodDictionary values do: [:each |
441
- Compiler new install: each source forClass: newClass class category: each category].
512
+ anotherClass comment: aClass comment.
442
513
 
443
- self setupClass: newClass.
444
- ^newClass
514
+ aClass methodDictionary values do: [ :each |
515
+ Compiler new install: each source forClass: anotherClass category: each category ].
516
+
517
+ aClass class methodDictionary values do: [ :each |
518
+ Compiler new install: each source forClass: anotherClass class category: each category ].
519
+
520
+ self basicClass: anotherClass class instanceVariables: aClass class instanceVariableNames.
521
+
522
+ self setupClass: anotherClass
445
523
  !
446
524
 
447
525
  instanceVariableNamesFor: aString
448
- ^(aString tokenize: ' ') reject: [:each | each isEmpty]
526
+ ^(aString tokenize: ' ') reject: [ :each | each isEmpty ]
449
527
  !
450
528
 
451
- setupClass: aClass
452
- <smalltalk.init(aClass);>
529
+ migrateClass: aClass superclass: anotherClass
530
+ self
531
+ migrateClassNamed: aClass name
532
+ superclass: anotherClass
533
+ instanceVariableNames: aClass instanceVariableNames
534
+ package: aClass package name
535
+ !
536
+
537
+ migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName
538
+ | oldClass newClass |
539
+
540
+ oldClass := Smalltalk current at: aString.
541
+
542
+ "Rename the old class for existing instances"
543
+ self basicRenameClass: oldClass to: 'Old', aString.
544
+
545
+ newClass := self
546
+ addSubclassOf: aClass
547
+ named: aString
548
+ instanceVariableNames: aCollection
549
+ package: packageName.
550
+
551
+ oldClass subclasses do: [ :each |
552
+ self migrateClass: each superclass: newClass ].
553
+
554
+ [ self copyClass: oldClass to: newClass ]
555
+ on: Error
556
+ do: [ :exception |
557
+ self
558
+ basicRemoveClass: newClass;
559
+ basicRenameClass: oldClass to: aString.
560
+ exception signal ].
561
+
562
+ self basicRemoveClass: oldClass.
563
+ ^newClass
453
564
  ! !
454
565
 
455
566
  Object subclass: #ClassCategoryReader
456
- instanceVariableNames: 'class category chunkParser'
567
+ instanceVariableNames: 'class category'
457
568
  package: 'Kernel-Classes'!
458
569
  !ClassCategoryReader commentStamp!
459
570
  ClassCategoryReader represents a mechanism for retrieving class descriptions stored on a file.!
@@ -472,14 +583,13 @@ scanFrom: aChunkParser
472
583
  [chunk := aChunkParser nextChunk.
473
584
  chunk isEmpty] whileFalse: [
474
585
  self compileMethod: chunk].
475
- Compiler new setupClass: class
586
+ ClassBuilder new setupClass: class
476
587
  ! !
477
588
 
478
589
  !ClassCategoryReader methodsFor: 'initialization'!
479
590
 
480
591
  initialize
481
592
  super initialize.
482
- chunkParser := ChunkParser new.
483
593
  ! !
484
594
 
485
595
  !ClassCategoryReader methodsFor: 'private'!
@@ -489,10 +599,10 @@ compileMethod: aString
489
599
  ! !
490
600
 
491
601
  Object subclass: #ClassCommentReader
492
- instanceVariableNames: 'class chunkParser'
602
+ instanceVariableNames: 'class'
493
603
  package: 'Kernel-Classes'!
494
604
  !ClassCommentReader commentStamp!
495
- ClassCommentReader represents a mechanism for retrieving class descriptions stored on a file.
605
+ ClassCommentReader represents a mechanism for retrieving class comments stored on a file.
496
606
  See `ClassCategoryReader` too.!
497
607
 
498
608
  !ClassCommentReader methodsFor: 'accessing'!
@@ -514,7 +624,6 @@ scanFrom: aChunkParser
514
624
 
515
625
  initialize
516
626
  super initialize.
517
- chunkParser := ChunkParser new.
518
627
  ! !
519
628
 
520
629
  !ClassCommentReader methodsFor: 'private'!