Browse Source

Better checking of supersend.

`'super' value` no longer considered being supersend.
Herbert Vojčík 7 years ago
parent
commit
3a83dfd7d9
4 changed files with 87 additions and 29 deletions
  1. 58 3
      src/Compiler-AST.js
  2. 9 1
      src/Compiler-AST.st
  3. 18 23
      src/Compiler-Semantic.js
  4. 2 2
      src/Compiler-Semantic.st

+ 58 - 3
src/Compiler-AST.js

@@ -387,6 +387,24 @@ messageSends: []
 }),
 $globals.Node);
 
+$core.addMethod(
+$core.method({
+selector: "isSuperKeyword",
+protocol: 'testing',
+fn: function (){
+var self=this;
+return false;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "isSuperKeyword\x0a\x09^ false",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.Node);
+
 $core.addMethod(
 $core.method({
 selector: "isValueNode",
@@ -2582,17 +2600,31 @@ var self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-return $recv($recv(self._receiver())._value()).__eq("super");
+var $2,$1;
+$2=self._receiver();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["receiver"]=1;
+//>>excludeEnd("ctx");
+$1=$recv($2)._notNil();
+return $recv($1)._and_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv(self._receiver())._isSuperKeyword();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"superSend",{},$globals.SendNode)});
 //>>excludeEnd("ctx");
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "superSend\x0a\x09^ self receiver value = 'super'",
+source: "superSend\x0a\x09^ self receiver notNil and: [ self receiver isSuperKeyword ]",
 referencedClasses: [],
 //>>excludeEnd("ide");
-messageSends: ["=", "value", "receiver"]
+messageSends: ["and:", "notNil", "receiver", "isSuperKeyword"]
 }),
 $globals.SendNode);
 
@@ -3176,6 +3208,29 @@ messageSends: []
 }),
 $globals.VariableNode);
 
+$core.addMethod(
+$core.method({
+selector: "isSuperKeyword",
+protocol: 'testing',
+fn: function (){
+var self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv(self._value()).__eq("super");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"isSuperKeyword",{},$globals.VariableNode)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "isSuperKeyword\x0a\x09^ self value = 'super'",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["=", "value"]
+}),
+$globals.VariableNode);
+
 $core.addMethod(
 $core.method({
 selector: "isVariableNode",

+ 9 - 1
src/Compiler-AST.st

@@ -190,6 +190,10 @@ isSequenceNode
 	^ false
 !
 
+isSuperKeyword
+	^ false
+!
+
 isValueNode
 	^ false
 !
@@ -564,7 +568,7 @@ selector: aString
 !
 
 superSend
-	^ self receiver value = 'super'
+	^ self receiver notNil and: [ self receiver isSuperKeyword ]
 ! !
 
 !SendNode methodsFor: 'building'!
@@ -767,6 +771,10 @@ isNavigationNode
 	^ true
 !
 
+isSuperKeyword
+	^ self value = 'super'
+!
+
 isVariableNode
 	^ true
 ! !

+ 18 - 23
src/Compiler-Semantic.js

@@ -2378,25 +2378,20 @@ var self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $3,$2,$1,$5,$6,$4,$7,$8,$9,$11,$12,$10,$receiver;
-$3=$recv(aNode)._receiver();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["receiver"]=1;
-//>>excludeEnd("ctx");
-$2=$recv($3)._value();
-$1=$recv($2).__eq("super");
+var $1,$3,$4,$2,$5,$6,$7,$9,$10,$8,$receiver;
+$1=$recv(aNode)._superSend();
 if(!$core.assert($1)){
-$5=$recv($globals.IRSendInliner)._inlinedSelectors();
-$6=$recv(aNode)._selector();
+$3=$recv($globals.IRSendInliner)._inlinedSelectors();
+$4=$recv(aNode)._selector();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["selector"]=1;
 //>>excludeEnd("ctx");
-$4=$recv($5)._includes_($6);
-if($core.assert($4)){
+$2=$recv($3)._includes_($4);
+if($core.assert($2)){
 $recv(aNode)._shouldBeInlined_(true);
-$7=$recv(aNode)._receiver();
-if(($receiver = $7) == null || $receiver.isNil){
-$7;
+$5=$recv(aNode)._receiver();
+if(($receiver = $5) == null || $receiver.isNil){
+$5;
 } else {
 var receiver;
 receiver=$receiver;
@@ -2404,15 +2399,15 @@ $recv(receiver)._shouldBeAliased_(true);
 };
 };
 };
-$8=self._messageSends();
+$6=self._messageSends();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["messageSends"]=1;
 //>>excludeEnd("ctx");
-$9=$recv(aNode)._selector();
+$7=$recv(aNode)._selector();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["selector"]=2;
 //>>excludeEnd("ctx");
-$recv($8)._at_ifAbsentPut_($9,(function(){
+$recv($6)._at_ifAbsentPut_($7,(function(){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx2) {
 //>>excludeEnd("ctx");
@@ -2421,19 +2416,19 @@ return $recv($globals.Set)._new();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,4)});
 //>>excludeEnd("ctx");
 }));
-$11=self._messageSends();
+$9=self._messageSends();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["messageSends"]=2;
 //>>excludeEnd("ctx");
-$12=$recv(aNode)._selector();
+$10=$recv(aNode)._selector();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["selector"]=3;
 //>>excludeEnd("ctx");
-$10=$recv($11)._at_($12);
+$8=$recv($9)._at_($10);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["at:"]=1;
 //>>excludeEnd("ctx");
-$recv($10)._add_(aNode);
+$recv($8)._add_(aNode);
 $recv(aNode)._index_($recv($recv(self._messageSends())._at_($recv(aNode)._selector()))._size());
 (
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -2450,10 +2445,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aNode"],
-source: "visitSendNode: aNode\x0a\x0a\x09aNode receiver value = 'super'\x0a\x09\x09ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [\x0a\x09\x09\x09aNode shouldBeInlined: true.\x0a\x09\x09\x09aNode receiver ifNotNil: [ :receiver |\x0a\x09\x09\x09\x09receiver shouldBeAliased: true ] ] ].\x0a\x0a\x09self messageSends at: aNode selector ifAbsentPut: [ Set new ].\x0a\x09(self messageSends at: aNode selector) add: aNode.\x0a\x0a\x09aNode index: (self messageSends at: aNode selector) size.\x0a\x0a\x09super visitSendNode: aNode",
+source: "visitSendNode: aNode\x0a\x0a\x09aNode superSend ifFalse: [ \x0a\x09\x09(IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [\x0a\x09\x09\x09aNode shouldBeInlined: true.\x0a\x09\x09\x09aNode receiver ifNotNil: [ :receiver |\x0a\x09\x09\x09\x09receiver shouldBeAliased: true ] ] ].\x0a\x0a\x09self messageSends at: aNode selector ifAbsentPut: [ Set new ].\x0a\x09(self messageSends at: aNode selector) add: aNode.\x0a\x0a\x09aNode index: (self messageSends at: aNode selector) size.\x0a\x0a\x09super visitSendNode: aNode",
 referencedClasses: ["IRSendInliner", "Set"],
 //>>excludeEnd("ide");
-messageSends: ["ifFalse:", "=", "value", "receiver", "ifTrue:", "includes:", "inlinedSelectors", "selector", "shouldBeInlined:", "ifNotNil:", "shouldBeAliased:", "at:ifAbsentPut:", "messageSends", "new", "add:", "at:", "index:", "size", "visitSendNode:"]
+messageSends: ["ifFalse:", "superSend", "ifTrue:", "includes:", "inlinedSelectors", "selector", "shouldBeInlined:", "ifNotNil:", "receiver", "shouldBeAliased:", "at:ifAbsentPut:", "messageSends", "new", "add:", "at:", "index:", "size", "visitSendNode:"]
 }),
 $globals.SemanticAnalyzer);
 

+ 2 - 2
src/Compiler-Semantic.st

@@ -583,8 +583,8 @@ visitReturnNode: aNode
 
 visitSendNode: aNode
 
-	aNode receiver value = 'super'
-		ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [
+	aNode superSend ifFalse: [ 
+		(IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [
 			aNode shouldBeInlined: true.
 			aNode receiver ifNotNil: [ :receiver |
 				receiver shouldBeAliased: true ] ] ].