19 次代碼提交 df6b0c728d ... 2c797d7cf8

作者 SHA1 備註 提交日期
  Herbert Vojčík 2c797d7cf8 Remove relic of copy-and-paste. 7 年之前
  Herbert Vojčík bc4324c4bf Remove late-binding, "import" as the rest. 7 年之前
  Herbert Vojčík 0b0d9b48a0 Merge {Methods,BehaviorProviders}Brik. 7 年之前
  Herbert Vojčík d9be913563 Working on 0.20.0 7 年之前
  Herbert Vojčík 20b0f6b964 Recompile (while version set to 0.19.1) 7 年之前
  Herbert Vojčík 18b9bd1488 Release version 0.19.1 7 年之前
  Herbert Vojčík 675e02781f Boolean >> == does not do unnecessary valueOf(). 7 年之前
  Herbert Vojčík 115ab5147a Last CHANGELOG touches. 7 年之前
  Herbert Vojčík 3f24ff8be8 Fix formatting of compiled .js files. 7 年之前
  Herby Vojčík 7a6e319a6d Merge branch 'add-math' of stevenremot/amber into master 7 年之前
  Steven Rémot 3ee20b0b23 Add new methods in API-CHANGES.txt 7 年之前
  Steven Rémot e32caa48e1 Add method to Point 7 年之前
  Steven Rémot 166193ffa6 Add Rectangle class and helpers 7 年之前
  Steven Rémot 4dfbe9fa97 Add methods to Number 7 年之前
  Herbert Vojčík c0a7e4556c Forgot API. 7 年之前
  Herbert Vojčík 596d090e95 Typo fix. 7 年之前
  Herbert Vojčík a22830ecf4 Simplify #{add,remove}CompiledMethod:. 7 年之前
  Herbert Vojčík 74d7197b66 Fix package rename bugs. 7 年之前
  Herbert Vojčík ff3c6b3a2b kernel: Move things around. 7 年之前

+ 32 - 2
API-CHANGES.txt

@@ -3,15 +3,16 @@
 * Deprecate amber/boot api nextId, prop globalJsVariables.
 * Remove amber/boot prop reservedWords (with the hope no one uses it directly).
 * Deprecate ProtoObject >> identityHash.
-* Deprecate SmalltalkImage >> packageAt: in favour of explicit #packageAt:ifAbsent:.
+* Deprecate SmalltalkImage >> packageAt: in favour of explicit #packageAt:if{Absent,Present}:.
 
 + AmberBootstrapInitialization class >>
   + run
   + initializeClasses
   + organizeClasses
-  + otganizeMethods
+  + organizeMethods
 + Behavior >>
   + basicOrganization
+  + basicOrganization:
 + ClassOrganizer >>
   + theClass
 + ClassOrganizer class >>
@@ -35,6 +36,7 @@
   + named:javaScriptDescriptor:
 + SmalltalkImage >>
   + packageDictionary
+  + packageAt:ifPresent:
 + TBehaviorProvider >>
   + methodOrganizationEnter:andLeave:
 + TMasterBehavior >>
@@ -46,6 +48,34 @@
   + basicOrganization:
 + UndefinedObject >>
   + ==
++ Number >>
+  + min:max:
+  + degreesToRadians
+  + radiansToDegrees
+  + arcTan:
+  + between:and:
++ Number class >>
+  + radiansPerDegree
++ Point >>
+  + dotProduct:
+  + normal
+  + angle
+  + normalized
+  + r
+  + corner:
+  + extent:
+  + rectangle:
++ Rectangle >>
+  + =
+  + corner
+  + origin
+  + containsPoint:
+  + containsRect:
+  + printOn:
++ Rectangle class >>
+  + origin:corner:
+  + origin:extent:
+  + point:point:
 
 - Package >>
   - basicName:

+ 2 - 1
CHANGELOG

@@ -1,4 +1,4 @@
-?? May 2017 - Release 0.19.1
+18 Jun 2017 - Release 0.19.1
 ===================================
 
 * Kernel slimmed, things moved to Smalltalk side.
@@ -12,6 +12,7 @@
   * TMasterBehavior >> enterOrganization
   * TMasterBehavior >> leaveOrganization
   * TBehaviorProvider >> methodOrganizationEnter:andLeave:
+* Set fix (#1224).
 
 Commits: https://lolg.it/amber/amber/commits/0.19.1.
 

File diff suppressed because it is too large
+ 660 - 357
external/amber-cli/support/amber-cli.js


+ 15 - 36
src/Kernel-Classes.js

@@ -2319,52 +2319,32 @@ var oldMethod,announcement;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $2,$3,$1,$4,$5,$6,$7,$8,$9,$10,$receiver;
+var $1,$2,$3,$4,$receiver;
 oldMethod=$recv($self._methodDictionary())._at_ifAbsent_($recv(aMethod)._selector(),(function(){
 return nil;
 
 }));
-$2=$self._protocols();
-$3=$recv(aMethod)._protocol();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["protocol"]=1;
-//>>excludeEnd("ctx");
-$1=$recv($2)._includes_($3);
-if(!$core.assert($1)){
-$4=$self._organization();
-$5=$recv(aMethod)._protocol();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["protocol"]=2;
-//>>excludeEnd("ctx");
-$recv($4)._addElement_($5);
-}
 $self._basicAddCompiledMethod_(aMethod);
-$6=oldMethod;
-if(($receiver = $6) == null || $receiver.a$nil){
-$6;
-} else {
-$self._removeProtocolIfEmpty_($recv(oldMethod)._protocol());
-}
-$7=oldMethod;
-if(($receiver = $7) == null || $receiver.a$nil){
-$8=$recv($globals.MethodAdded)._new();
+$1=oldMethod;
+if(($receiver = $1) == null || $receiver.a$nil){
+$2=$recv($globals.MethodAdded)._new();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["new"]=1;
 //>>excludeEnd("ctx");
-$recv($8)._method_(aMethod);
+$recv($2)._method_(aMethod);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["method:"]=1;
 //>>excludeEnd("ctx");
-$9=$recv($8)._yourself();
+$3=$recv($2)._yourself();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["yourself"]=1;
 //>>excludeEnd("ctx");
-announcement=$9;
+announcement=$3;
 } else {
-$10=$recv($globals.MethodModified)._new();
-$recv($10)._oldMethod_(oldMethod);
-$recv($10)._method_(aMethod);
-announcement=$recv($10)._yourself();
+$4=$recv($globals.MethodModified)._new();
+$recv($4)._oldMethod_(oldMethod);
+$recv($4)._method_(aMethod);
+announcement=$recv($4)._yourself();
 }
 $recv($recv($globals.SystemAnnouncer)._current())._announce_(announcement);
 return self;
@@ -2374,10 +2354,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aMethod"],
-source: "addCompiledMethod: aMethod\x0a\x09| oldMethod announcement |\x0a\x09\x0a\x09oldMethod := self methodDictionary\x0a\x09\x09at: aMethod selector\x0a\x09\x09ifAbsent: [ nil ].\x0a\x09\x0a\x09(self protocols includes: aMethod protocol)\x0a\x09\x09ifFalse: [ self organization addElement: aMethod protocol ].\x0a\x0a\x09self basicAddCompiledMethod: aMethod.\x0a\x09\x0a\x09oldMethod ifNotNil: [\x0a\x09\x09self removeProtocolIfEmpty: oldMethod protocol ].\x0a\x09\x0a\x09announcement := oldMethod\x0a\x09\x09ifNil: [\x0a\x09\x09\x09MethodAdded new\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ]\x0a\x09\x09ifNotNil: [\x0a\x09\x09\x09MethodModified new\x0a\x09\x09\x09\x09\x09oldMethod: oldMethod;\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ].\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09\x09\x09announce: announcement",
+source: "addCompiledMethod: aMethod\x0a\x09| oldMethod announcement |\x0a\x09\x0a\x09oldMethod := self methodDictionary\x0a\x09\x09at: aMethod selector\x0a\x09\x09ifAbsent: [ nil ].\x0a\x09\x0a\x09self basicAddCompiledMethod: aMethod.\x0a\x09\x0a\x09announcement := oldMethod\x0a\x09\x09ifNil: [\x0a\x09\x09\x09MethodAdded new\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ]\x0a\x09\x09ifNotNil: [\x0a\x09\x09\x09MethodModified new\x0a\x09\x09\x09\x09\x09oldMethod: oldMethod;\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ].\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09\x09\x09announce: announcement",
 referencedClasses: ["MethodAdded", "MethodModified", "SystemAnnouncer"],
 //>>excludeEnd("ide");
-messageSends: ["at:ifAbsent:", "methodDictionary", "selector", "ifFalse:", "includes:", "protocols", "protocol", "addElement:", "organization", "basicAddCompiledMethod:", "ifNotNil:", "removeProtocolIfEmpty:", "ifNil:ifNotNil:", "method:", "new", "yourself", "oldMethod:", "announce:", "current"]
+messageSends: ["at:ifAbsent:", "methodDictionary", "selector", "basicAddCompiledMethod:", "ifNil:ifNotNil:", "method:", "new", "yourself", "oldMethod:", "announce:", "current"]
 }),
 $globals.TBehaviorProvider);
 
@@ -2968,7 +2948,6 @@ return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 var $1,$3,$2;
 $self._basicRemoveCompiledMethod_(aMethod);
-$self._removeProtocolIfEmpty_($recv(aMethod)._protocol());
 $1=$recv($globals.SystemAnnouncer)._current();
 $3=$recv($globals.MethodRemoved)._new();
 $recv($3)._method_(aMethod);
@@ -2981,10 +2960,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aMethod"],
-source: "removeCompiledMethod: aMethod\x0a\x09self basicRemoveCompiledMethod: aMethod.\x0a\x09\x0a\x09self removeProtocolIfEmpty: aMethod protocol.\x0a\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09announce: (MethodRemoved new\x0a\x09\x09\x09method: aMethod;\x0a\x09\x09\x09yourself)",
+source: "removeCompiledMethod: aMethod\x0a\x09self basicRemoveCompiledMethod: aMethod.\x0a\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09announce: (MethodRemoved new\x0a\x09\x09\x09method: aMethod;\x0a\x09\x09\x09yourself)",
 referencedClasses: ["SystemAnnouncer", "MethodRemoved"],
 //>>excludeEnd("ide");
-messageSends: ["basicRemoveCompiledMethod:", "removeProtocolIfEmpty:", "protocol", "announce:", "current", "method:", "new", "yourself"]
+messageSends: ["basicRemoveCompiledMethod:", "announce:", "current", "method:", "new", "yourself"]
 }),
 $globals.TBehaviorProvider);
 

+ 0 - 8
src/Kernel-Classes.st

@@ -736,14 +736,8 @@ addCompiledMethod: aMethod
 		at: aMethod selector
 		ifAbsent: [ nil ].
 	
-	(self protocols includes: aMethod protocol)
-		ifFalse: [ self organization addElement: aMethod protocol ].
-
 	self basicAddCompiledMethod: aMethod.
 	
-	oldMethod ifNotNil: [
-		self removeProtocolIfEmpty: oldMethod protocol ].
-	
 	announcement := oldMethod
 		ifNil: [
 			MethodAdded new
@@ -774,8 +768,6 @@ recompile
 removeCompiledMethod: aMethod
 	self basicRemoveCompiledMethod: aMethod.
 	
-	self removeProtocolIfEmpty: aMethod protocol.
-	
 	SystemAnnouncer current
 		announce: (MethodRemoved new
 			method: aMethod;

+ 26 - 6
src/Kernel-Infrastructure.js

@@ -3475,6 +3475,29 @@ messageSends: ["at:ifAbsent:", "packageDictionary"]
 }),
 $globals.SmalltalkImage);
 
+$core.addMethod(
+$core.method({
+selector: "packageAt:ifPresent:",
+protocol: "packages",
+fn: function (packageName,aBlock){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._packageDictionary())._at_ifPresent_(packageName,aBlock);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"packageAt:ifPresent:",{packageName:packageName,aBlock:aBlock},$globals.SmalltalkImage)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["packageName", "aBlock"],
+source: "packageAt: packageName ifPresent: aBlock\x0a\x09^ self packageDictionary at: packageName ifPresent: aBlock",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["at:ifPresent:", "packageDictionary"]
+}),
+$globals.SmalltalkImage);
+
 $core.addMethod(
 $core.method({
 selector: "packageDictionary",
@@ -3822,10 +3845,7 @@ $ctx2.sendIdx["error:"]=1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
 //>>excludeEnd("ctx");
 }));
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["packageAt:ifAbsent:"]=1;
-//>>excludeEnd("ctx");
-$self._packageAt_ifAbsent_(newName,(function(){
+$self._packageAt_ifPresent_(newName,(function(){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx2) {
 //>>excludeEnd("ctx");
@@ -3847,10 +3867,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["packageName", "newName"],
-source: "renamePackage: packageName to: newName\x0a\x09\x22Rename a package.\x22\x0a\x0a\x09| pkg |\x0a\x09pkg := self packageAt: packageName ifAbsent: [ self error: 'Missing package: ', packageName ].\x0a\x09self packageAt: newName ifAbsent: [ self error: 'Already exists a package called: ', newName ].\x0a\x09pkg name: newName; beDirty.\x0a\x09self packageDictionary\x0a\x09\x09at: newName put: pkg;\x0a\x09\x09removeKey: packageName",
+source: "renamePackage: packageName to: newName\x0a\x09\x22Rename a package.\x22\x0a\x0a\x09| pkg |\x0a\x09pkg := self packageAt: packageName ifAbsent: [ self error: 'Missing package: ', packageName ].\x0a\x09self packageAt: newName ifPresent: [ self error: 'Already exists a package called: ', newName ].\x0a\x09pkg name: newName; beDirty.\x0a\x09self packageDictionary\x0a\x09\x09at: newName put: pkg;\x0a\x09\x09removeKey: packageName",
 referencedClasses: [],
 //>>excludeEnd("ide");
-messageSends: ["packageAt:ifAbsent:", "error:", ",", "name:", "beDirty", "at:put:", "packageDictionary", "removeKey:"]
+messageSends: ["packageAt:ifAbsent:", "error:", ",", "packageAt:ifPresent:", "name:", "beDirty", "at:put:", "packageDictionary", "removeKey:"]
 }),
 $globals.SmalltalkImage);
 

+ 5 - 1
src/Kernel-Infrastructure.st

@@ -980,6 +980,10 @@ packageAt: packageName ifAbsent: aBlock
 	^ self packageDictionary at: packageName ifAbsent: aBlock
 !
 
+packageAt: packageName ifPresent: aBlock
+	^ self packageDictionary at: packageName ifPresent: aBlock
+!
+
 packageDictionary
 	^ packageDictionary ifNil: [ packageDictionary := Dictionary new ]
 !
@@ -1005,7 +1009,7 @@ renamePackage: packageName to: newName
 
 	| pkg |
 	pkg := self packageAt: packageName ifAbsent: [ self error: 'Missing package: ', packageName ].
-	self packageAt: newName ifAbsent: [ self error: 'Already exists a package called: ', newName ].
+	self packageAt: newName ifPresent: [ self error: 'Already exists a package called: ', newName ].
 	pkg name: newName; beDirty.
 	self packageDictionary
 		at: newName put: pkg;

+ 688 - 3
src/Kernel-Objects.js

@@ -1761,8 +1761,8 @@ var self=this,$self=this;
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 
-	if (typeof aBoolean === "boolean") return self.valueOf() === aBoolean;
-	else if (aBoolean != null && typeof aBoolean === "object") return self.valueOf() === aBoolean.valueOf();
+	if (typeof aBoolean === "boolean") return (self == true) === aBoolean;
+	else if (aBoolean != null && typeof aBoolean === "object") return (self == true) === aBoolean.valueOf();
 	else return false;;
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -1771,7 +1771,7 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aBoolean"],
-source: "== aBoolean\x0a<inlineJS: '\x0a\x09if (typeof aBoolean === \x22boolean\x22) return self.valueOf() === aBoolean;\x0a\x09else if (aBoolean != null && typeof aBoolean === \x22object\x22) return self.valueOf() === aBoolean.valueOf();\x0a\x09else return false;\x0a'>",
+source: "== aBoolean\x0a<inlineJS: '\x0a\x09if (typeof aBoolean === \x22boolean\x22) return (self == true) === aBoolean;\x0a\x09else if (aBoolean != null && typeof aBoolean === \x22object\x22) return (self == true) === aBoolean.valueOf();\x0a\x09else return false;\x0a'>",
 referencedClasses: [],
 //>>excludeEnd("ide");
 messageSends: []
@@ -3616,6 +3616,30 @@ messageSends: []
 }),
 $globals.Number);
 
+$core.addMethod(
+$core.method({
+selector: "arcTan:",
+protocol: "mathematical functions",
+fn: function (aNumber){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return Math.atan2(self, aNumber);;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"arcTan:",{aNumber:aNumber},$globals.Number)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aNumber"],
+source: "arcTan: aNumber\x0a\x09<inlineJS: 'return Math.atan2(self, aNumber);'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.Number);
+
 $core.addMethod(
 $core.method({
 selector: "asJavaScriptObject",
@@ -3750,6 +3774,37 @@ messageSends: ["+", "truncated", "*", "next", "new"]
 }),
 $globals.Number);
 
+$core.addMethod(
+$core.method({
+selector: "between:and:",
+protocol: "testing",
+fn: function (min,max){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self.__gt_eq(min))._and_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $self.__lt_eq(max);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"between:and:",{min:min,max:max},$globals.Number)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["min", "max"],
+source: "between: min and: max\x0a ^ self >= min and: [ self <= max ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["and:", ">=", "<="]
+}),
+$globals.Number);
+
 $core.addMethod(
 $core.method({
 selector: "ceiling",
@@ -3839,6 +3894,29 @@ messageSends: ["copy"]
 }),
 $globals.Number);
 
+$core.addMethod(
+$core.method({
+selector: "degreesToRadians",
+protocol: "converting",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $self.__star($recv($globals.Number)._radiansPerDegree());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"degreesToRadians",{},$globals.Number)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "degreesToRadians\x0a\x09^ self * Number radiansPerDegree",
+referencedClasses: ["Number"],
+//>>excludeEnd("ide");
+messageSends: ["*", "radiansPerDegree"]
+}),
+$globals.Number);
+
 $core.addMethod(
 $core.method({
 selector: "even",
@@ -4065,6 +4143,29 @@ messageSends: []
 }),
 $globals.Number);
 
+$core.addMethod(
+$core.method({
+selector: "min:max:",
+protocol: "arithmetic",
+fn: function (aMin,aMax){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._min_(aMin))._max_(aMax);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"min:max:",{aMin:aMin,aMax:aMax},$globals.Number)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aMin", "aMax"],
+source: "min: aMin max: aMax\x0a\x09^ (self min: aMin) max: aMax",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["max:", "min:"]
+}),
+$globals.Number);
+
 $core.addMethod(
 $core.method({
 selector: "negated",
@@ -4205,6 +4306,29 @@ messageSends: []
 }),
 $globals.Number);
 
+$core.addMethod(
+$core.method({
+selector: "radiansToDegrees",
+protocol: "converting",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $self.__slash($recv($globals.Number)._radiansPerDegree());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"radiansToDegrees",{},$globals.Number)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "radiansToDegrees\x0a\x09^ self / Number radiansPerDegree",
+referencedClasses: ["Number"],
+//>>excludeEnd("ide");
+messageSends: ["/", "radiansPerDegree"]
+}),
+$globals.Number);
+
 $core.addMethod(
 $core.method({
 selector: "raisedTo:",
@@ -4815,6 +4939,29 @@ messageSends: []
 }),
 $globals.Number.a$cls);
 
+$core.addMethod(
+$core.method({
+selector: "radiansPerDegree",
+protocol: "instance creation",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._pi()).__slash((180));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"radiansPerDegree",{},$globals.Number.a$cls)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "radiansPerDegree\x0a\x09^ (self pi) / 180",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["/", "pi"]
+}),
+$globals.Number.a$cls);
+
 
 $core.addClass("Point", $globals.Object, ["x", "y"], "Kernel-Objects");
 //>>excludeStart("ide", pragmas.excludeIdeData);
@@ -5217,6 +5364,29 @@ messageSends: ["and:", ">=", "x", "y"]
 }),
 $globals.Point);
 
+$core.addMethod(
+$core.method({
+selector: "angle",
+protocol: "geometry",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._y())._arcTan_($self._x());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"angle",{},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "angle\x0a\x09^ self y arcTan: self x",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["arcTan:", "y", "x"]
+}),
+$globals.Point);
+
 $core.addMethod(
 $core.method({
 selector: "asPoint",
@@ -5235,6 +5405,29 @@ messageSends: []
 }),
 $globals.Point);
 
+$core.addMethod(
+$core.method({
+selector: "corner:",
+protocol: "rectangle creation",
+fn: function (aPoint){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($globals.Rectangle)._origin_corner_(self,aPoint);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"corner:",{aPoint:aPoint},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aPoint"],
+source: "corner: aPoint\x0a\x09^ Rectangle origin: self corner: aPoint",
+referencedClasses: ["Rectangle"],
+//>>excludeEnd("ide");
+messageSends: ["origin:corner:"]
+}),
+$globals.Point);
+
 $core.addMethod(
 $core.method({
 selector: "dist:",
@@ -5270,6 +5463,145 @@ messageSends: ["-", "x", "y", "sqrt", "+", "*"]
 }),
 $globals.Point);
 
+$core.addMethod(
+$core.method({
+selector: "dotProduct:",
+protocol: "point functions",
+fn: function (aPoint){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+$1=$recv($self["@x"]).__star($recv(aPoint)._x());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["*"]=1;
+//>>excludeEnd("ctx");
+return $recv($1).__plus($recv($self["@y"]).__star($recv(aPoint)._y()));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"dotProduct:",{aPoint:aPoint},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aPoint"],
+source: "dotProduct: aPoint\x0a\x09^ (x * aPoint x) + (y * aPoint y)",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["+", "*", "x", "y"]
+}),
+$globals.Point);
+
+$core.addMethod(
+$core.method({
+selector: "extent:",
+protocol: "rectangle creation",
+fn: function (aPoint){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($globals.Rectangle)._origin_extent_(self,aPoint);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"extent:",{aPoint:aPoint},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aPoint"],
+source: "extent: aPoint\x0a\x09^ Rectangle origin: self extent: aPoint",
+referencedClasses: ["Rectangle"],
+//>>excludeEnd("ide");
+messageSends: ["origin:extent:"]
+}),
+$globals.Point);
+
+$core.addMethod(
+$core.method({
+selector: "normal",
+protocol: "point functions",
+fn: function (){
+var self=this,$self=this;
+var n,d;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $4,$3,$6,$5,$2,$1;
+n=$recv($recv($self["@y"])._negated()).__at($self["@x"]);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$4=$recv(n)._x();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["x"]=1;
+//>>excludeEnd("ctx");
+$3=$recv($4).__star($recv(n)._x());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["*"]=1;
+//>>excludeEnd("ctx");
+$6=$recv(n)._y();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["y"]=1;
+//>>excludeEnd("ctx");
+$5=$recv($6).__star($recv(n)._y());
+d=$recv($3).__plus($5);
+$2=d;
+$1=$recv($2).__eq((0));
+if($core.assert($1)){
+return (-1).__at((0));
+}
+return $recv(n).__slash($recv(d)._sqrt());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"normal",{n:n,d:d},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "normal\x0a\x09\x22Answer a Point representing the unit vector rotated 90 deg clockwise. For the zero point return -1@0.\x22\x0a\x0a\x09| n d |\x0a\x09n := y negated @ x.\x0a\x09(d := (n x * n x + (n y * n y))) = 0\x0a\x09\x09 ifTrue: [ ^ -1 @0 ].\x0a\x09^ n / d sqrt",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["@", "negated", "ifTrue:", "=", "+", "*", "x", "y", "/", "sqrt"]
+}),
+$globals.Point);
+
+$core.addMethod(
+$core.method({
+selector: "normalized",
+protocol: "point functions",
+fn: function (){
+var self=this,$self=this;
+var r;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2,$3;
+r=$self._r();
+$1=$recv(r).__eq((0));
+if($core.assert($1)){
+$2=$recv($globals.Point)._x_y_((0),(0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["x:y:"]=1;
+//>>excludeEnd("ctx");
+return $2;
+} else {
+$3=$recv($self["@x"]).__slash(r);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["/"]=1;
+//>>excludeEnd("ctx");
+return $recv($globals.Point)._x_y_($3,$recv($self["@y"]).__slash(r));
+}
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"normalized",{r:r},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "normalized\x0a\x09| r |\x0a\x09r := self r.\x0a\x09\x0a\x09r = 0\x0a\x09\x09ifTrue: [ ^ Point x: 0 y: 0 ]\x0a\x09\x09ifFalse: [ ^ Point x: x / r y: y / r ]",
+referencedClasses: ["Point"],
+//>>excludeEnd("ide");
+messageSends: ["r", "ifTrue:ifFalse:", "=", "x:y:", "/"]
+}),
+$globals.Point);
+
 $core.addMethod(
 $core.method({
 selector: "printOn:",
@@ -5312,6 +5644,58 @@ messageSends: ["printOn:", "nextPutAll:", "ifTrue:", "and:", "notNil", "negative
 }),
 $globals.Point);
 
+$core.addMethod(
+$core.method({
+selector: "r",
+protocol: "polar coordinates",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $2,$1;
+$2=$recv($self["@x"]).__star($self["@x"]);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["*"]=1;
+//>>excludeEnd("ctx");
+$1=$recv($2).__plus($recv($self["@y"]).__star($self["@y"]));
+return $recv($1)._sqrt();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"r",{},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "r\x0a\x09^ ((x * x) + (y * y)) sqrt",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["sqrt", "+", "*"]
+}),
+$globals.Point);
+
+$core.addMethod(
+$core.method({
+selector: "rectangle:",
+protocol: "rectangle creation",
+fn: function (aPoint){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($globals.Rectangle)._point_point_(self,aPoint);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"rectangle:",{aPoint:aPoint},$globals.Point)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aPoint"],
+source: "rectangle: aPoint\x0a\x09^ Rectangle point: self point: aPoint",
+referencedClasses: ["Rectangle"],
+//>>excludeEnd("ide");
+messageSends: ["point:point:"]
+}),
+$globals.Point);
+
 $core.addMethod(
 $core.method({
 selector: "translateBy:",
@@ -5522,6 +5906,307 @@ $globals.Random);
 
 
 
+$core.addClass("Rectangle", $globals.Object, ["origin", "corner"], "Kernel-Objects");
+//>>excludeStart("ide", pragmas.excludeIdeData);
+$globals.Rectangle.comment="I represent a Rectangle defined by my two corners.\x0a\x0aThe simplest way to create an instance is using Point methods:\x0a\x0a    1@1 corner: 2@2\x0a\x0aWIll create a rectangle with 1@1 as the top left and 2@2 at the bottom right.\x0a\x0a    1@1 extent: 1@1\x0a\x0aWill create the same rectangle, defining an origin and a size instead of an origin and a corner.";
+//>>excludeEnd("ide");
+$core.addMethod(
+$core.method({
+selector: "=",
+protocol: "testing",
+fn: function (aRectangle){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+$1=$recv($self["@origin"]).__eq($recv(aRectangle)._origin());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["="]=1;
+//>>excludeEnd("ctx");
+return $recv($1)._and_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($self["@corner"]).__eq($recv(aRectangle)._corner());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"=",{aRectangle:aRectangle},$globals.Rectangle)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aRectangle"],
+source: "= aRectangle\x0a\x09^ origin = aRectangle origin and: [ corner = aRectangle corner ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["and:", "=", "origin", "corner"]
+}),
+$globals.Rectangle);
+
+$core.addMethod(
+$core.method({
+selector: "containsPoint:",
+protocol: "testing",
+fn: function (aPoint){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($recv($self["@origin"]).__lt_eq(aPoint))._and_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($self["@corner"]).__gt_eq(aPoint);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"containsPoint:",{aPoint:aPoint},$globals.Rectangle)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aPoint"],
+source: "containsPoint: aPoint\x0a\x09^ origin <= aPoint and: [ corner >= aPoint ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["and:", "<=", ">="]
+}),
+$globals.Rectangle);
+
+$core.addMethod(
+$core.method({
+selector: "containsRect:",
+protocol: "testing",
+fn: function (aRect){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($recv($recv(aRect)._origin()).__gt_eq($self["@origin"]))._and_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($recv(aRect)._corner()).__lt_eq($self["@corner"]);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"containsRect:",{aRect:aRect},$globals.Rectangle)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aRect"],
+source: "containsRect: aRect\x0a\x09^ aRect origin >= origin and: [ aRect corner <= corner ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["and:", ">=", "origin", "<=", "corner"]
+}),
+$globals.Rectangle);
+
+$core.addMethod(
+$core.method({
+selector: "corner",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+return $self["@corner"];
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "corner\x0a\x09^ corner",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.Rectangle);
+
+$core.addMethod(
+$core.method({
+selector: "origin",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+return $self["@origin"];
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "origin\x0a\x09^ origin",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.Rectangle);
+
+$core.addMethod(
+$core.method({
+selector: "printOn:",
+protocol: "testing",
+fn: function (aStream){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+$recv($self["@origin"])._printOn_(aStream);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["printOn:"]=1;
+//>>excludeEnd("ctx");
+$recv(aStream)._nextPutAll_(" corner: ");
+$recv($self["@corner"])._printOn_(aStream);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"printOn:",{aStream:aStream},$globals.Rectangle)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aStream"],
+source: "printOn: aStream\x0a\x09origin printOn: aStream.\x0a\x09aStream nextPutAll: ' corner: '.\x0a\x09corner printOn: aStream.",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["printOn:", "nextPutAll:"]
+}),
+$globals.Rectangle);
+
+$core.addMethod(
+$core.method({
+selector: "setPoint:point:",
+protocol: "private",
+fn: function (pt1,pt2){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $2,$3,$1,$5,$6,$4,$8,$7,$10,$9;
+$2=$recv(pt1)._x();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["x"]=1;
+//>>excludeEnd("ctx");
+$3=$recv(pt2)._x();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["x"]=2;
+//>>excludeEnd("ctx");
+$1=$recv($2)._min_($3);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["min:"]=1;
+//>>excludeEnd("ctx");
+$5=$recv(pt1)._y();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["y"]=1;
+//>>excludeEnd("ctx");
+$6=$recv(pt2)._y();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["y"]=2;
+//>>excludeEnd("ctx");
+$4=$recv($5)._min_($6);
+$self["@origin"]=$recv($1).__at($4);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$8=$recv(pt1)._x();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["x"]=3;
+//>>excludeEnd("ctx");
+$7=$recv($8)._max_($recv(pt2)._x());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["max:"]=1;
+//>>excludeEnd("ctx");
+$10=$recv(pt1)._y();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["y"]=3;
+//>>excludeEnd("ctx");
+$9=$recv($10)._max_($recv(pt2)._y());
+$self["@corner"]=$recv($7).__at($9);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"setPoint:point:",{pt1:pt1,pt2:pt2},$globals.Rectangle)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["pt1", "pt2"],
+source: "setPoint: pt1 point: pt2\x0a\x0a\x09origin := (pt1 x min: pt2 x)@(pt1 y min: pt2 y).\x0a\x09corner := (pt1 x max: pt2 x)@(pt1 y max: pt2 y).",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["@", "min:", "x", "y", "max:"]
+}),
+$globals.Rectangle);
+
+
+$core.addMethod(
+$core.method({
+selector: "origin:corner:",
+protocol: "instance creation",
+fn: function (anOrigin,aCorner){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._basicNew())._setPoint_point_(anOrigin,aCorner);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"origin:corner:",{anOrigin:anOrigin,aCorner:aCorner},$globals.Rectangle.a$cls)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anOrigin", "aCorner"],
+source: "origin: anOrigin corner: aCorner\x0a\x09^ self basicNew setPoint: anOrigin point: aCorner.",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["setPoint:point:", "basicNew"]
+}),
+$globals.Rectangle.a$cls);
+
+$core.addMethod(
+$core.method({
+selector: "origin:extent:",
+protocol: "instance creation",
+fn: function (anOrigin,anExtent){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._basicNew())._setPoint_point_(anOrigin,$recv(anOrigin).__plus(anExtent));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"origin:extent:",{anOrigin:anOrigin,anExtent:anExtent},$globals.Rectangle.a$cls)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anOrigin", "anExtent"],
+source: "origin: anOrigin extent: anExtent\x0a\x09^ self basicNew setPoint: anOrigin point: anOrigin + anExtent.",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["setPoint:point:", "basicNew", "+"]
+}),
+$globals.Rectangle.a$cls);
+
+$core.addMethod(
+$core.method({
+selector: "point:point:",
+protocol: "instance creation",
+fn: function (anOrigin,aCorner){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._basicNew())._setPoint_point_(anOrigin,aCorner);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"point:point:",{anOrigin:anOrigin,aCorner:aCorner},$globals.Rectangle.a$cls)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anOrigin", "aCorner"],
+source: "point: anOrigin point: aCorner\x0a\x09^ self basicNew setPoint: anOrigin point: aCorner.",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["setPoint:point:", "basicNew"]
+}),
+$globals.Rectangle.a$cls);
+
+
 $core.addClass("UndefinedObject", $globals.Object, [], "Kernel-Objects");
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.UndefinedObject.comment="I describe the behavior of my sole instance, `nil`. `nil` represents a prior value for variables that have not been initialized, or for results which are meaningless.\x0a\x0a`nil` is the Smalltalk equivalent of the `undefined` JavaScript object.\x0a\x0a__note:__ When sending messages to the `undefined` JavaScript object, it will be replaced by `nil`.";

+ 145 - 2
src/Kernel-Objects.st

@@ -438,8 +438,8 @@ I am directly mapped to JavaScript Boolean. The `true` and `false` objects are t
 
 == aBoolean
 <inlineJS: '
-	if (typeof aBoolean === "boolean") return self.valueOf() === aBoolean;
-	else if (aBoolean !!= null && typeof aBoolean === "object") return self.valueOf() === aBoolean.valueOf();
+	if (typeof aBoolean === "boolean") return (self == true) === aBoolean;
+	else if (aBoolean !!= null && typeof aBoolean === "object") return (self == true) === aBoolean.valueOf();
 	else return false;
 '>
 ! !
@@ -816,6 +816,10 @@ min: aNumber
 	<inlineJS: 'return Math.min(self, aNumber);'>
 !
 
+min: aMin max: aMax
+	^ (self min: aMin) max: aMax
+!
+
 negated
 	^ 0 - self
 ! !
@@ -888,10 +892,18 @@ ceiling
 	<inlineJS: 'return Math.ceil(self);'>
 !
 
+degreesToRadians
+	^ self * Number radiansPerDegree
+!
+
 floor
 	<inlineJS: 'return Math.floor(self);'>
 !
 
+radiansToDegrees
+	^ self / Number radiansPerDegree
+!
+
 rounded
 	<inlineJS: 'return Math.round(self);'>
 !
@@ -1002,6 +1014,10 @@ arcTan
 	<inlineJS: 'return Math.atan(self);'>
 !
 
+arcTan: aNumber
+	<inlineJS: 'return Math.atan2(self, aNumber);'>
+!
+
 cos
 	<inlineJS: 'return Math.cos(self);'>
 !
@@ -1058,6 +1074,10 @@ printShowingDecimalPlaces: placesDesired
 
 !Number methodsFor: 'testing'!
 
+between: min and: max
+ ^ self >= min and: [ self <= max ]
+!
+
 even
 	^ 0 = (self \\ 2)
 !
@@ -1108,6 +1128,10 @@ e
 
 pi
 	<inlineJS: 'return Math.PI'>
+!
+
+radiansPerDegree
+	^ (self pi) / 180
 ! !
 
 Object subclass: #Point
@@ -1203,6 +1227,43 @@ asPoint
 	^ self
 ! !
 
+!Point methodsFor: 'geometry'!
+
+angle
+	^ self y arcTan: self x
+! !
+
+!Point methodsFor: 'point functions'!
+
+dotProduct: aPoint
+	^ (x * aPoint x) + (y * aPoint y)
+!
+
+normal
+	"Answer a Point representing the unit vector rotated 90 deg clockwise. For the zero point return -1@0."
+
+	| n d |
+	n := y negated @ x.
+	(d := (n x * n x + (n y * n y))) = 0
+		 ifTrue: [ ^ -1 @0 ].
+	^ n / d sqrt
+!
+
+normalized
+	| r |
+	r := self r.
+	
+	r = 0
+		ifTrue: [ ^ Point x: 0 y: 0 ]
+		ifFalse: [ ^ Point x: x / r y: y / r ]
+! !
+
+!Point methodsFor: 'polar coordinates'!
+
+r
+	^ ((x * x) + (y * y)) sqrt
+! !
+
 !Point methodsFor: 'printing'!
 
 printOn: aStream
@@ -1218,6 +1279,20 @@ printOn: aStream
 	y printOn: aStream
 ! !
 
+!Point methodsFor: 'rectangle creation'!
+
+corner: aPoint
+	^ Rectangle origin: self corner: aPoint
+!
+
+extent: aPoint
+	^ Rectangle origin: self extent: aPoint
+!
+
+rectangle: aPoint
+	^ Rectangle point: self point: aPoint
+! !
+
 !Point methodsFor: 'transforming'!
 
 dist: aPoint 
@@ -1296,6 +1371,74 @@ next: anInteger
 	^ (1 to: anInteger) collect: [ :each | self next ]
 ! !
 
+Object subclass: #Rectangle
+	instanceVariableNames: 'origin corner'
+	package: 'Kernel-Objects'!
+!Rectangle commentStamp!
+I represent a Rectangle defined by my two corners.
+
+The simplest way to create an instance is using Point methods:
+
+    1@1 corner: 2@2
+
+WIll create a rectangle with 1@1 as the top left and 2@2 at the bottom right.
+
+    1@1 extent: 1@1
+
+Will create the same rectangle, defining an origin and a size instead of an origin and a corner.!
+
+!Rectangle methodsFor: 'accessing'!
+
+corner
+	^ corner
+!
+
+origin
+	^ origin
+! !
+
+!Rectangle methodsFor: 'private'!
+
+setPoint: pt1 point: pt2
+
+	origin := (pt1 x min: pt2 x)@(pt1 y min: pt2 y).
+	corner := (pt1 x max: pt2 x)@(pt1 y max: pt2 y).
+! !
+
+!Rectangle methodsFor: 'testing'!
+
+= aRectangle
+	^ origin = aRectangle origin and: [ corner = aRectangle corner ]
+!
+
+containsPoint: aPoint
+	^ origin <= aPoint and: [ corner >= aPoint ]
+!
+
+containsRect: aRect
+	^ aRect origin >= origin and: [ aRect corner <= corner ]
+!
+
+printOn: aStream
+	origin printOn: aStream.
+	aStream nextPutAll: ' corner: '.
+	corner printOn: aStream.
+! !
+
+!Rectangle class methodsFor: 'instance creation'!
+
+origin: anOrigin corner: aCorner
+	^ self basicNew setPoint: anOrigin point: aCorner.
+!
+
+origin: anOrigin extent: anExtent
+	^ self basicNew setPoint: anOrigin point: anOrigin + anExtent.
+!
+
+point: anOrigin point: aCorner
+	^ self basicNew setPoint: anOrigin point: aCorner.
+! !
+
 Object subclass: #UndefinedObject
 	instanceVariableNames: ''
 	package: 'Kernel-Objects'!

+ 562 - 5
src/Kernel-Tests.js

@@ -12211,6 +12211,60 @@ messageSends: ["assert:equals:", "asNumber"]
 }),
 $globals.NumberTest);
 
+$core.addMethod(
+$core.method({
+selector: "testBetweenAnd",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$3,$2,$5,$4;
+$1=(4)._between_and_((3),(5));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["between:and:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_($1);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:"]=1;
+//>>excludeEnd("ctx");
+$3=(1)._between_and_((5),(6));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["between:and:"]=2;
+//>>excludeEnd("ctx");
+$2=$recv($3)._not();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["not"]=1;
+//>>excludeEnd("ctx");
+$self._assert_($2);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:"]=2;
+//>>excludeEnd("ctx");
+$5=(90)._between_and_((67),(87));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["between:and:"]=3;
+//>>excludeEnd("ctx");
+$4=$recv($5)._not();
+$self._assert_($4);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:"]=3;
+//>>excludeEnd("ctx");
+$self._assert_((1)._between_and_((1),(1)));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testBetweenAnd",{},$globals.NumberTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testBetweenAnd\x0a\x09self assert: (4 between: 3 and: 5).\x0a\x09self assert: (1 between: 5 and: 6) not.\x0a\x09self assert: (90 between: 67 and: 87) not.\x0a\x09self assert: (1 between: 1 and: 1).",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["assert:", "between:and:", "not"]
+}),
+$globals.NumberTest);
+
 $core.addMethod(
 $core.method({
 selector: "testCeiling",
@@ -12351,6 +12405,30 @@ messageSends: ["assert:", "==", "copy", "deepCopy"]
 }),
 $globals.NumberTest);
 
+$core.addMethod(
+$core.method({
+selector: "testDegreesToRadians",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+$self._assert_($recv($recv($recv((180)._degreesToRadians()).__minus($recv($globals.Number)._pi()))._abs()).__lt_eq((0.01)));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testDegreesToRadians",{},$globals.NumberTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testDegreesToRadians\x0a\x09self assert: (180 degreesToRadians - Number pi) abs <= 0.01.",
+referencedClasses: ["Number"],
+//>>excludeEnd("ide");
+messageSends: ["assert:", "<=", "abs", "-", "degreesToRadians", "pi"]
+}),
+$globals.NumberTest);
+
 $core.addMethod(
 $core.method({
 selector: "testEquality",
@@ -13202,11 +13280,32 @@ var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
+var $1,$2;
 $self._assert_equals_((2)._max_((5)),(5));
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["assert:equals:"]=1;
 //>>excludeEnd("ctx");
 $self._assert_equals_((2)._min_((5)),(2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=2;
+//>>excludeEnd("ctx");
+$1=(2)._min_max_((5),(3));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["min:max:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_equals_($1,(3));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=3;
+//>>excludeEnd("ctx");
+$2=(7)._min_max_((5),(3));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["min:max:"]=2;
+//>>excludeEnd("ctx");
+$self._assert_equals_($2,(5));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=4;
+//>>excludeEnd("ctx");
+$self._assert_equals_((4)._min_max_((5),(3)),(4));
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"testMinMax",{},$globals.NumberTest)});
@@ -13214,10 +13313,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "testMinMax\x0a\x09\x0a\x09self assert: (2 max: 5) equals: 5.\x0a\x09self assert: (2 min: 5) equals: 2",
+source: "testMinMax\x0a\x09\x0a\x09self assert: (2 max: 5) equals: 5.\x0a\x09self assert: (2 min: 5) equals: 2.\x0a\x09self assert: (2 min: 5 max: 3) equals: 3.\x0a\x09self assert: (7 min: 5 max: 3) equals: 5.\x0a\x09self assert: (4 min: 5 max: 3) equals: 4.",
 referencedClasses: [],
 //>>excludeEnd("ide");
-messageSends: ["assert:equals:", "max:", "min:"]
+messageSends: ["assert:equals:", "max:", "min:", "min:max:"]
 }),
 $globals.NumberTest);
 
@@ -13387,6 +13486,30 @@ messageSends: ["assert:equals:", "printShowingDecimalPlaces:", "negated"]
 }),
 $globals.NumberTest);
 
+$core.addMethod(
+$core.method({
+selector: "testRadiansToDegrees",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+$self._assert_($recv($recv($recv($recv($recv($globals.Number)._pi())._radiansToDegrees()).__minus((180)))._abs()).__lt_eq((0.01)));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRadiansToDegrees",{},$globals.NumberTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRadiansToDegrees\x0a\x09self assert: (Number pi radiansToDegrees - 180) abs <= 0.01.",
+referencedClasses: ["Number"],
+//>>excludeEnd("ide");
+messageSends: ["assert:", "<=", "abs", "-", "radiansToDegrees", "pi"]
+}),
+$globals.NumberTest);
+
 $core.addMethod(
 $core.method({
 selector: "testRaisedTo",
@@ -13706,6 +13829,7 @@ var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
+var $1;
 $self._assert_equals_((0)._cos(),(1));
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["assert:equals:"]=1;
@@ -13727,6 +13851,18 @@ $self._assert_equals_((0)._arcSin(),(0));
 $ctx1.sendIdx["assert:equals:"]=5;
 //>>excludeEnd("ctx");
 $self._assert_equals_((0)._arcTan(),(0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=6;
+//>>excludeEnd("ctx");
+$1=(0)._arcTan_((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["arcTan:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_equals_($1,(0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=7;
+//>>excludeEnd("ctx");
+$self._assert_equals_((1)._arcTan_((0)),$recv($recv($globals.Number)._pi()).__slash((2)));
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"testTrigonometry",{},$globals.NumberTest)});
@@ -13734,10 +13870,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "testTrigonometry\x0a\x09self assert: 0 cos equals: 1.\x0a\x09self assert: 0 sin equals: 0.\x0a\x09self assert: 0 tan equals: 0.\x0a\x09self assert: 1 arcCos equals: 0.\x0a\x09self assert: 0 arcSin equals: 0.\x0a\x09self assert: 0 arcTan equals: 0.",
-referencedClasses: [],
+source: "testTrigonometry\x0a\x09self assert: 0 cos equals: 1.\x0a\x09self assert: 0 sin equals: 0.\x0a\x09self assert: 0 tan equals: 0.\x0a\x09self assert: 1 arcCos equals: 0.\x0a\x09self assert: 0 arcSin equals: 0.\x0a\x09self assert: 0 arcTan equals: 0.\x0a\x09\x0a\x09self assert: (0 arcTan: 1) equals: 0.\x0a\x09self assert: (1 arcTan: 0) equals: (Number pi / 2)",
+referencedClasses: ["Number"],
 //>>excludeEnd("ide");
-messageSends: ["assert:equals:", "cos", "sin", "tan", "arcCos", "arcSin", "arcTan"]
+messageSends: ["assert:equals:", "cos", "sin", "tan", "arcCos", "arcSin", "arcTan", "arcTan:", "/", "pi"]
 }),
 $globals.NumberTest);
 
@@ -14337,6 +14473,30 @@ messageSends: ["assert:equals:", "x", "x:y:", "y", "x:", "new", "y:"]
 }),
 $globals.PointTest);
 
+$core.addMethod(
+$core.method({
+selector: "testAngle",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+$self._assert_equals_($recv((-1).__at((0)))._angle(),$recv($globals.Number)._pi());
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testAngle",{},$globals.PointTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testAngle\x0a\x09self assert: (-1@0) angle equals: Number pi",
+referencedClasses: ["Number"],
+//>>excludeEnd("ide");
+messageSends: ["assert:equals:", "angle", "@", "pi"]
+}),
+$globals.PointTest);
+
 $core.addMethod(
 $core.method({
 selector: "testArithmetic",
@@ -14572,6 +14732,36 @@ messageSends: ["assert:", "<", "@", "deny:", "<=", ">", ">="]
 }),
 $globals.PointTest);
 
+$core.addMethod(
+$core.method({
+selector: "testDotProduct",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $2,$1;
+$2=(2).__at((3));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$1=$recv($2)._dotProduct_((3).__at((7)));
+$self._assert_equals_($1,(27));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testDotProduct",{},$globals.PointTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testDotProduct\x0a\x09self assert: (2@3 dotProduct: 3@7) equals: 27",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["assert:equals:", "dotProduct:", "@"]
+}),
+$globals.PointTest);
+
 $core.addMethod(
 $core.method({
 selector: "testEgality",
@@ -14683,6 +14873,202 @@ messageSends: ["assert:equals:", "y", "x:", "new", "deny:", "=", "x", "y:"]
 }),
 $globals.PointTest);
 
+$core.addMethod(
+$core.method({
+selector: "testNormal",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $2,$1;
+$2=(1).__at((0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$1=$recv($2)._normal();
+$self._assert_equals_($1,(0).__at((1)));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testNormal",{},$globals.PointTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testNormal\x0a\x09self assert: (1@0) normal equals: 0@1",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["assert:equals:", "normal", "@"]
+}),
+$globals.PointTest);
+
+$core.addMethod(
+$core.method({
+selector: "testNormalized",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $2,$1,$3,$5,$4;
+$2=(0).__at((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$1=$recv($2)._normalized();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["normalized"]=1;
+//>>excludeEnd("ctx");
+$3=(0).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=2;
+//>>excludeEnd("ctx");
+$self._assert_equals_($1,$3);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=1;
+//>>excludeEnd("ctx");
+$5=(0).__at((0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=3;
+//>>excludeEnd("ctx");
+$4=$recv($5)._normalized();
+$self._assert_equals_($4,(0).__at((0)));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testNormalized",{},$globals.PointTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testNormalized\x0a\x09self assert: (0@2) normalized equals: 0@1.\x0a\x09self assert: (0@0) normalized equals: 0@0.",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["assert:equals:", "normalized", "@"]
+}),
+$globals.PointTest);
+
+$core.addMethod(
+$core.method({
+selector: "testPolarCoordinates",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $2,$1;
+$2=(1).__at((0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$1=$recv($2)._r();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["r"]=1;
+//>>excludeEnd("ctx");
+$self._assert_equals_($1,(1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_equals_($recv((0).__at((0)))._r(),(0));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testPolarCoordinates",{},$globals.PointTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testPolarCoordinates\x0a\x09self assert: (1@0) r equals: 1.\x0a\x09self assert: (0@0) r equals: 0.",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["assert:equals:", "r", "@"]
+}),
+$globals.PointTest);
+
+$core.addMethod(
+$core.method({
+selector: "testRectangleCreation",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $2,$3,$1,$5,$6,$4,$8,$9,$7,$11,$12,$10,$14,$15,$13,$17,$16;
+$2=(1).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$3=(2).__at((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=2;
+//>>excludeEnd("ctx");
+$1=$recv($2)._corner_($3);
+$5=(1).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=3;
+//>>excludeEnd("ctx");
+$6=(2).__at((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=4;
+//>>excludeEnd("ctx");
+$4=$recv($globals.Rectangle)._origin_corner_($5,$6);
+$self._assert_equals_($1,$4);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=1;
+//>>excludeEnd("ctx");
+$8=(1).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=5;
+//>>excludeEnd("ctx");
+$9=(2).__at((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=6;
+//>>excludeEnd("ctx");
+$7=$recv($8)._rectangle_($9);
+$11=(1).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=7;
+//>>excludeEnd("ctx");
+$12=(2).__at((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=8;
+//>>excludeEnd("ctx");
+$10=$recv($globals.Rectangle)._point_point_($11,$12);
+$self._assert_equals_($7,$10);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=2;
+//>>excludeEnd("ctx");
+$14=(1).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=9;
+//>>excludeEnd("ctx");
+$15=(2).__at((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=10;
+//>>excludeEnd("ctx");
+$13=$recv($14)._extent_($15);
+$17=(1).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=11;
+//>>excludeEnd("ctx");
+$16=$recv($globals.Rectangle)._origin_extent_($17,(2).__at((2)));
+$self._assert_equals_($13,$16);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRectangleCreation",{},$globals.PointTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRectangleCreation\x0a\x09self assert: (1@1 corner: 2@2) equals: (Rectangle origin: 1@1 corner: 2@2).\x0a\x09self assert: (1@1 rectangle: 2@2) equals: (Rectangle point: 1@1 point: 2@2).\x0a\x09self assert: (1@1 extent: 2@2) equals: (Rectangle origin: 1@1 extent: 2@2)",
+referencedClasses: ["Rectangle"],
+//>>excludeEnd("ide");
+messageSends: ["assert:equals:", "corner:", "@", "origin:corner:", "rectangle:", "point:point:", "extent:", "origin:extent:"]
+}),
+$globals.PointTest);
+
 $core.addMethod(
 $core.method({
 selector: "testTranslateBy",
@@ -15016,6 +15402,177 @@ $globals.RandomTest);
 
 
 
+$core.addClass("RectangleTest", $globals.TestCase, [], "Kernel-Tests");
+$core.addMethod(
+$core.method({
+selector: "testContainsPoint",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var rect;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2,$4,$5,$3;
+$1=(0).__at((0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$2=(4).__at((4));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=2;
+//>>excludeEnd("ctx");
+rect=$recv($globals.Rectangle)._origin_corner_($1,$2);
+$4=rect;
+$5=(1).__at((2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=3;
+//>>excludeEnd("ctx");
+$3=$recv($4)._containsPoint_($5);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["containsPoint:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_($3);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_($recv($recv(rect)._containsPoint_((5).__at((4))))._not());
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testContainsPoint",{rect:rect},$globals.RectangleTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testContainsPoint\x0a\x09| rect |\x0a\x09rect := Rectangle origin: 0@0 corner: 4@4.\x0a\x09\x0a\x09self assert: (rect containsPoint: 1@2).\x0a\x09self assert: (rect containsPoint: 5@4) not.",
+referencedClasses: ["Rectangle"],
+//>>excludeEnd("ide");
+messageSends: ["origin:corner:", "@", "assert:", "containsPoint:", "not"]
+}),
+$globals.RectangleTest);
+
+$core.addMethod(
+$core.method({
+selector: "testContainsRect",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $3,$4,$2,$6,$7,$5,$1,$11,$12,$10,$14,$13,$9,$8;
+$3=(0).__at((0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$4=(6).__at((6));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=2;
+//>>excludeEnd("ctx");
+$2=$recv($globals.Rectangle)._origin_corner_($3,$4);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["origin:corner:"]=1;
+//>>excludeEnd("ctx");
+$6=(1).__at((1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=3;
+//>>excludeEnd("ctx");
+$7=(5).__at((5));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=4;
+//>>excludeEnd("ctx");
+$5=$recv($globals.Rectangle)._origin_corner_($6,$7);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["origin:corner:"]=2;
+//>>excludeEnd("ctx");
+$1=$recv($2)._containsRect_($5);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["containsRect:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_($1);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:"]=1;
+//>>excludeEnd("ctx");
+$11=(0).__at((0));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=5;
+//>>excludeEnd("ctx");
+$12=(6).__at((6));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=6;
+//>>excludeEnd("ctx");
+$10=$recv($globals.Rectangle)._origin_corner_($11,$12);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["origin:corner:"]=3;
+//>>excludeEnd("ctx");
+$14=(1).__at((-1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=7;
+//>>excludeEnd("ctx");
+$13=$recv($globals.Rectangle)._origin_corner_($14,(5).__at((5)));
+$9=$recv($10)._containsRect_($13);
+$8=$recv($9)._not();
+$self._assert_($8);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testContainsRect",{},$globals.RectangleTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testContainsRect\x0a\x09self assert: ((Rectangle origin: 0@0 corner: 6@6) containsRect: (Rectangle origin: 1@1 corner: 5@5)).\x0a\x09self assert: ((Rectangle origin: 0@0 corner: 6@6) containsRect: (Rectangle origin: 1@(-1) corner: 5@5)) not.",
+referencedClasses: ["Rectangle"],
+//>>excludeEnd("ide");
+messageSends: ["assert:", "containsRect:", "origin:corner:", "@", "not"]
+}),
+$globals.RectangleTest);
+
+$core.addMethod(
+$core.method({
+selector: "testOriginExtent",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+var rectangle;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2,$3,$4;
+$1=(3).__at((4));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=1;
+//>>excludeEnd("ctx");
+$2=(7).__at((8));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=2;
+//>>excludeEnd("ctx");
+rectangle=$recv($globals.Rectangle)._origin_extent_($1,$2);
+$3=$recv(rectangle)._origin();
+$4=(3).__at((4));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["@"]=3;
+//>>excludeEnd("ctx");
+$self._assert_equals_($3,$4);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_equals_($recv(rectangle)._corner(),(10).__at((12)));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testOriginExtent",{rectangle:rectangle},$globals.RectangleTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testOriginExtent\x0a\x09| rectangle |\x0a\x09rectangle := Rectangle origin: 3@4 extent: 7@8.\x0a\x09\x0a\x09self assert: rectangle origin equals: 3@4.\x0a\x09self assert: rectangle corner equals: 10@12.",
+referencedClasses: ["Rectangle"],
+//>>excludeEnd("ide");
+messageSends: ["origin:extent:", "@", "assert:equals:", "origin", "corner"]
+}),
+$globals.RectangleTest);
+
+
+
 $core.addClass("StreamTest", $globals.TestCase, [], "Kernel-Tests");
 $core.addMethod(
 $core.method({

+ 77 - 1
src/Kernel-Tests.st

@@ -2271,6 +2271,13 @@ testAsNumber
 	self assert: 3 asNumber equals: 3.
 !
 
+testBetweenAnd
+	self assert: (4 between: 3 and: 5).
+	self assert: (1 between: 5 and: 6) not.
+	self assert: (90 between: 67 and: 87) not.
+	self assert: (1 between: 1 and: 1).
+!
+
 testCeiling
 	self assert: 1.2 ceiling equals: 2.
 	self assert: -1.2 ceiling equals: -1.
@@ -2296,6 +2303,10 @@ testCopying
 	self assert: 1 deepCopy == 1
 !
 
+testDegreesToRadians
+	self assert: (180 degreesToRadians - Number pi) abs <= 0.01.
+!
+
 testEquality
 	self assert: (1 = 1).
 	self assert: (0 = 0).
@@ -2394,7 +2405,10 @@ testLog
 testMinMax
 	
 	self assert: (2 max: 5) equals: 5.
-	self assert: (2 min: 5) equals: 2
+	self assert: (2 min: 5) equals: 2.
+	self assert: (2 min: 5 max: 3) equals: 3.
+	self assert: (7 min: 5 max: 3) equals: 5.
+	self assert: (4 min: 5 max: 3) equals: 4.
 !
 
 testNegated
@@ -2418,6 +2432,10 @@ testPrintShowingDecimalPlaces
 	self assert: (0 printShowingDecimalPlaces: 2) equals: '0.00'.
 !
 
+testRadiansToDegrees
+	self assert: (Number pi radiansToDegrees - 180) abs <= 0.01.
+!
+
 testRaisedTo
 	self assert: (2 raisedTo: 4) equals: 16.
 	self assert: (2 raisedTo: 0) equals: 1.
@@ -2479,6 +2497,9 @@ testTrigonometry
 	self assert: 1 arcCos equals: 0.
 	self assert: 0 arcSin equals: 0.
 	self assert: 0 arcTan equals: 0.
+	
+	self assert: (0 arcTan: 1) equals: 0.
+	self assert: (1 arcTan: 0) equals: (Number pi / 2)
 !
 
 testTruncated
@@ -2602,6 +2623,10 @@ testAccessing
 	self assert: (Point new y: 4) y equals: 4
 !
 
+testAngle
+	self assert: (-1@0) angle equals: Number pi
+!
+
 testArithmetic
 	self assert: 3@4 * (3@4 ) equals: (Point x: 9 y: 16).
 	self assert: 3@4 + (3@4 ) equals: (Point x: 6 y: 8).
@@ -2627,6 +2652,10 @@ testComparison
 	self deny: 4@5 >= (5@5)
 !
 
+testDotProduct
+	self assert: (2@3 dotProduct: 3@7) equals: 27
+!
+
 testEgality
 	self assert: (3@4 = (3@4)).
 	self deny: 3@5 = (3@6)
@@ -2640,6 +2669,26 @@ testNew
 	self deny: (Point new y: 4) y = 0
 !
 
+testNormal
+	self assert: (1@0) normal equals: 0@1
+!
+
+testNormalized
+	self assert: (0@2) normalized equals: 0@1.
+	self assert: (0@0) normalized equals: 0@0.
+!
+
+testPolarCoordinates
+	self assert: (1@0) r equals: 1.
+	self assert: (0@0) r equals: 0.
+!
+
+testRectangleCreation
+	self assert: (1@1 corner: 2@2) equals: (Rectangle origin: 1@1 corner: 2@2).
+	self assert: (1@1 rectangle: 2@2) equals: (Rectangle point: 1@1 point: 2@2).
+	self assert: (1@1 extent: 2@2) equals: (Rectangle origin: 1@1 extent: 2@2)
+!
+
 testTranslateBy
 	self assert: (3@3 translateBy: 0@1) equals: 3@4.
 	self assert: (3@3 translateBy: 0@1 negated) equals: 3@2.
@@ -2710,6 +2759,33 @@ textNext
 			next = current ]
 ! !
 
+TestCase subclass: #RectangleTest
+	instanceVariableNames: ''
+	package: 'Kernel-Tests'!
+
+!RectangleTest methodsFor: 'tests'!
+
+testContainsPoint
+	| rect |
+	rect := Rectangle origin: 0@0 corner: 4@4.
+	
+	self assert: (rect containsPoint: 1@2).
+	self assert: (rect containsPoint: 5@4) not.
+!
+
+testContainsRect
+	self assert: ((Rectangle origin: 0@0 corner: 6@6) containsRect: (Rectangle origin: 1@1 corner: 5@5)).
+	self assert: ((Rectangle origin: 0@0 corner: 6@6) containsRect: (Rectangle origin: 1@(-1) corner: 5@5)) not.
+!
+
+testOriginExtent
+	| rectangle |
+	rectangle := Rectangle origin: 3@4 extent: 7@8.
+	
+	self assert: rectangle origin equals: 3@4.
+	self assert: rectangle corner equals: 10@12.
+! !
+
 TestCase subclass: #StreamTest
 	instanceVariableNames: ''
 	package: 'Kernel-Tests'!

+ 2 - 13
src/Platform-Services.js

@@ -1162,17 +1162,6 @@ var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $1,$2,$receiver;
-$1=$recv($recv($globals.Smalltalk)._globals())._at_(aNewPackageName);
-if(($receiver = $1) == null || $receiver.a$nil){
-$1;
-} else {
-$2=$recv("A package named ".__comma(aNewPackageName)).__comma(" already exists");
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx[","]=1;
-//>>excludeEnd("ctx");
-$self._error_($2);
-}
 $recv($globals.Smalltalk)._renamePackage_to_(aPackageName,aNewPackageName);
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -1181,10 +1170,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aPackageName", "aNewPackageName"],
-source: "renamePackage: aPackageName to: aNewPackageName\x0a        (Smalltalk globals at: aNewPackageName)\x0a                ifNotNil: [ self error: 'A package named ', aNewPackageName, ' already exists' ].\x0a\x0a        Smalltalk renamePackage: aPackageName to: aNewPackageName",
+source: "renamePackage: aPackageName to: aNewPackageName\x0a        Smalltalk renamePackage: aPackageName to: aNewPackageName",
 referencedClasses: ["Smalltalk"],
 //>>excludeEnd("ide");
-messageSends: ["ifNotNil:", "at:", "globals", "error:", ",", "renamePackage:to:"]
+messageSends: ["renamePackage:to:"]
 }),
 $globals.Environment);
 

+ 0 - 3
src/Platform-Services.st

@@ -208,9 +208,6 @@ renameClass: aClass to: aClassName
 !
 
 renamePackage: aPackageName to: aNewPackageName
-        (Smalltalk globals at: aNewPackageName)
-                ifNotNil: [ self error: 'A package named ', aNewPackageName, ' already exists' ].
-
         Smalltalk renamePackage: aPackageName to: aNewPackageName
 !
 

+ 23 - 0
support/boot.js

@@ -72,6 +72,28 @@ define([
         st.defaultAmdNamespace = st.defaultAmdNamespace || "amber_core";
     }
 
+    /* Defines asReceiver to be present at load time */
+    /* (logically it belongs more to PrimitiveBrik) */
+    AsReceiverBrik.deps = ["nil"];
+    function AsReceiverBrik (brikz, st) {
+        var nilAsReceiver = brikz.nil.nilAsReceiver;
+
+        /**
+         * This function is used all over the compiled amber code.
+         * It takes any value (JavaScript or Smalltalk)
+         * and returns a proper Amber Smalltalk receiver.
+         *
+         * null or undefined -> nilAsReceiver,
+         * object having Smalltalk signature -> unchanged,
+         * otherwise wrapped foreign (JS) object
+         */
+        this.asReceiver = function (o) {
+            if (o == null) return nilAsReceiver;
+            else if (o.a$cls != null) return o;
+            else return st.wrapJavaScript(o);
+        };
+    }
+
     var api = {};
     var brikz = new Brikz(api);
 
@@ -79,6 +101,7 @@ define([
 
     configureWithHierarchy(brikz);
 
+    brikz.asReceiver = AsReceiverBrik;
     brikz.stInit = SmalltalkInitBrik;
     brikz.amd = AMDBrik;
 

+ 34 - 7
support/kernel-fundamentals.js

@@ -181,10 +181,9 @@ define(['./compatibility' /* TODO remove */], function () {
         };
     }
 
-    MethodsBrik.deps = ["behaviorProviders", "selectors", "root", "selectorConversion"];
+    MethodsBrik.deps = ["selectors", "root", "selectorConversion"];
     function MethodsBrik (brikz, st) {
         var registerSelector = brikz.selectors.registerSelector;
-        var updateMethod = brikz.behaviorProviders.updateMethod;
         var SmalltalkObject = brikz.root.Object;
         var coreFns = brikz.root.coreFns;
 
@@ -245,15 +244,13 @@ define(['./compatibility' /* TODO remove */], function () {
             delete traitOrBehavior.localMethods[method.selector];
             updateMethod(method.selector, traitOrBehavior);
         };
-    }
 
-    function BehaviorProvidersBrik (brikz, st) {
         this.setupMethods = function (traitOrBehavior) {
             traitOrBehavior.localMethods = Object.create(null);
             traitOrBehavior.methods = Object.create(null);
         };
 
-        this.updateMethod = function (selector, traitOrBehavior) {
+        function updateMethod (selector, traitOrBehavior) {
             var oldMethod = traitOrBehavior.methods[selector],
                 newMethod = traitOrBehavior.localMethods[selector];
             if (oldMethod == null && newMethod == null) {
@@ -269,7 +266,9 @@ define(['./compatibility' /* TODO remove */], function () {
                 traitOrBehavior.methodRemoved(oldMethod);
             }
             if (st._methodReplaced) st._methodReplaced(newMethod, oldMethod, traitOrBehavior);
-        };
+        }
+
+        this.updateMethod = updateMethod;
     }
 
     function ArraySetBrik (brikz, st) {
@@ -351,16 +350,44 @@ define(['./compatibility' /* TODO remove */], function () {
         };
     }
 
+    NilBrik.deps = ["root"];
+    function NilBrik (brikz, st) {
+        var SmalltalkObject = brikz.root.Object;
+        var coreFns = brikz.root.coreFns;
+
+        function SmalltalkNil () {
+        }
+
+        coreFns.UndefinedObject = inherits(SmalltalkNil, SmalltalkObject);
+
+        this.nilAsReceiver = new SmalltalkNil();
+        this.nilAsValue = this.nilAsReceiver; // TODO null
+
+        // Adds an `a$nil` (and legacy `isNil`) property to the `nil` object.  When sending
+        // nil objects from one environment to another, doing
+        // `anObject == nil` (in JavaScript) does not always answer
+        // true as the referenced nil object might come from the other
+        // environment.
+        Object.defineProperty(this.nilAsReceiver, 'a$nil', {
+            value: true,
+            enumerable: false, configurable: false, writable: false
+        });
+        Object.defineProperty(this.nilAsReceiver, 'isNil', {
+            value: true,
+            enumerable: false, configurable: false, writable: false
+        });
+    }
+
     /* Making smalltalk that has basic building blocks */
 
     function configureWithFundamentals (brikz) {
         brikz.smalltalkGlobals = SmalltalkGlobalsBrik;
         brikz.root = RootBrik;
+        brikz.nil = NilBrik;
         brikz.arraySet = ArraySetBrik;
         brikz.selectorConversion = SelectorConversionBrik;
         brikz.selectors = SelectorsBrik;
         brikz.packages = PackagesBrik;
-        brikz.behaviorProviders = BehaviorProvidersBrik;
         brikz.behaviors = BehaviorsBrik;
         brikz.methods = MethodsBrik;
 

+ 6 - 58
support/kernel-language.js

@@ -59,11 +59,11 @@ define(['./compatibility' /* TODO remove */], function () {
         });
     }
 
-    TraitsBrik.deps = ["behaviors", "behaviorProviders", "composition", "arraySet", "root"];
+    TraitsBrik.deps = ["behaviors", "methods", "composition", "arraySet", "root"];
     function TraitsBrik (brikz, st) {
         var coreFns = brikz.root.coreFns;
         var SmalltalkObject = brikz.root.Object;
-        var setupMethods = brikz.behaviorProviders.setupMethods;
+        var setupMethods = brikz.methods.setupMethods;
         var traitMethodChanged = brikz.composition.traitMethodChanged;
         var buildTraitOrClass = brikz.behaviors.buildTraitOrClass;
         var addElement = brikz.arraySet.addElement;
@@ -126,9 +126,9 @@ define(['./compatibility' /* TODO remove */], function () {
         };
     }
 
-    MethodCompositionBrik.deps = ["behaviorProviders"];
+    MethodCompositionBrik.deps = ["methods"];
     function MethodCompositionBrik (brikz, st) {
-        var updateMethod = brikz.behaviorProviders.updateMethod;
+        var updateMethod = brikz.methods.updateMethod;
 
         function aliased (selector, method) {
             if (method.selector === selector) return method;
@@ -249,14 +249,14 @@ define(['./compatibility' /* TODO remove */], function () {
         this.traitMethodChanged = traitMethodChanged;
     }
 
-    ClassesBrik.deps = ["root", "behaviors", "behaviorProviders", "arraySet", "smalltalkGlobals"];
+    ClassesBrik.deps = ["root", "behaviors", "methods", "arraySet", "smalltalkGlobals"];
     function ClassesBrik (brikz, st) {
         var SmalltalkRoot = brikz.root.Root;
         var coreFns = brikz.root.coreFns;
         var globals = brikz.smalltalkGlobals.globals;
         var SmalltalkObject = brikz.root.Object;
         var buildTraitOrClass = brikz.behaviors.buildTraitOrClass;
-        var setupMethods = brikz.behaviorProviders.setupMethods;
+        var setupMethods = brikz.methods.setupMethods;
         var removeTraitOrClass = brikz.behaviors.removeTraitOrClass;
         var addElement = brikz.arraySet.addElement;
         var removeElement = brikz.arraySet.removeElement;
@@ -429,64 +429,12 @@ define(['./compatibility' /* TODO remove */], function () {
         };
     }
 
-    NilBrik.deps = ["root"];
-    function NilBrik (brikz, st) {
-        var SmalltalkObject = brikz.root.Object;
-        var coreFns = brikz.root.coreFns;
-
-        function SmalltalkNil () {
-        }
-
-        coreFns.UndefinedObject = inherits(SmalltalkNil, SmalltalkObject);
-
-        this.nilAsReceiver = new SmalltalkNil();
-        this.nilAsValue = this.nilAsReceiver; // TODO null
-
-        // Adds an `a$nil` (and legacy `isNil`) property to the `nil` object.  When sending
-        // nil objects from one environment to another, doing
-        // `anObject == nil` (in JavaScript) does not always answer
-        // true as the referenced nil object might come from the other
-        // environment.
-        Object.defineProperty(this.nilAsReceiver, 'a$nil', {
-            value: true,
-            enumerable: false, configurable: false, writable: false
-        });
-        Object.defineProperty(this.nilAsReceiver, 'isNil', {
-            value: true,
-            enumerable: false, configurable: false, writable: false
-        });
-    }
-
-    /* Defines asReceiver to be present at load time */
-    /* (logically it belongs more to PrimitiveBrik) */
-    AsReceiverBrik.deps = ["nil"];
-    function AsReceiverBrik (brikz, st) {
-        var nilAsReceiver = brikz.nil.nilAsReceiver;
-
-        /**
-         * This function is used all over the compiled amber code.
-         * It takes any value (JavaScript or Smalltalk)
-         * and returns a proper Amber Smalltalk receiver.
-         *
-         * null or undefined -> nilAsReceiver,
-         * object having Smalltalk signature -> unchanged,
-         * otherwise wrapped foreign (JS) object
-         */
-        this.asReceiver = function (o) {
-            if (o == null) return nilAsReceiver;
-            else if (o.a$cls != null) return o;
-            else return st.wrapJavaScript(o);
-        };
-    }
-
     /* Making smalltalk that can load */
 
     function configureWithHierarchy (brikz) {
         brikz.traits = TraitsBrik;
         brikz.composition = MethodCompositionBrik;
         brikz.classes = ClassesBrik;
-        brikz.nil = NilBrik;
-        brikz.asReceiver = AsReceiverBrik;
 
         brikz.rebuild();
     }

+ 3 - 3
support/kernel-runtime.js

@@ -12,7 +12,7 @@ define(function () {
 
     DNUBrik.deps = ["selectors", "smalltalkGlobals", "manipulation", "classes"];
     function DNUBrik (brikz, st) {
-        var selectorsBrik = brikz.selectors;
+        var selectorPairs = brikz.selectors.selectorPairs;
         var globals = brikz.smalltalkGlobals.globals;
         var installJSMethod = brikz.manipulation.installJSMethod;
         var nilAsClass = brikz.classes.nilAsClass;
@@ -40,7 +40,7 @@ define(function () {
             };
         }
 
-        selectorsBrik.selectorPairs.forEach(function (pair) {
+        selectorPairs.forEach(function (pair) {
             makeDnuHandler(pair, []);
         });
     }
@@ -325,7 +325,7 @@ define(function () {
          The effect is, $core.seamless(fn)'s exceptions are not
          handed into ST error handler and caller should process them.
          */
-        st.seamless = function inContext (worker) {
+        st.seamless = function (worker) {
             var oldContext = thisContext;
             thisContext = new SmalltalkMethodContext(thisContext, function (ctx) {
                 ctx.fill(null, "seamlessDoIt", {}, globals.UndefinedObject);

Some files were not shown because too many files changed in this diff