1
0
Selaa lähdekoodia

Move jsOverride: marking to AST.

So it is known to ASTInterpreter and ASTDebugger.
Herby Vojčík 5 vuotta sitten
vanhempi
commit
b0540240c2

+ 38 - 1
lang/src/Compiler-AST.js

@@ -977,7 +977,7 @@ $globals.DynamicDictionaryNode);
 
 
 
-$core.addClass("SendNode", $globals.ExpressionNode, ["selector", "arguments", "receiver", "index", "isSideEffect"], "Compiler-AST");
+$core.addClass("SendNode", $globals.ExpressionNode, ["selector", "arguments", "receiver", "index", "javaScriptSelector", "isSideEffect"], "Compiler-AST");
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.SendNode.comment="I represent an message send node.";
 //>>excludeEnd("ide");
@@ -1194,6 +1194,43 @@ return $1;
 }; }),
 $globals.SendNode);
 
+$core.addMethod(
+$core.method({
+selector: "javaScriptSelector",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "javaScriptSelector\x0a\x09^ javaScriptSelector",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: []
+}, function ($methodClass){ return function (){
+var self=this,$self=this;
+return $self.javaScriptSelector;
+
+}; }),
+$globals.SendNode);
+
+$core.addMethod(
+$core.method({
+selector: "javaScriptSelector:",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aString"],
+source: "javaScriptSelector: aString\x0a\x09javaScriptSelector := aString",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: []
+}, function ($methodClass){ return function (aString){
+var self=this,$self=this;
+$self.javaScriptSelector=aString;
+return self;
+
+}; }),
+$globals.SendNode);
+
 $core.addMethod(
 $core.method({
 selector: "navigationLink",

+ 9 - 1
lang/src/Compiler-AST.st

@@ -256,7 +256,7 @@ acceptDagVisitor: aVisitor
 ! !
 
 ExpressionNode subclass: #SendNode
-	slots: {#selector. #arguments. #receiver. #index. #isSideEffect}
+	slots: {#selector. #arguments. #receiver. #index. #javaScriptSelector. #isSideEffect}
 	package: 'Compiler-AST'!
 !SendNode commentStamp!
 I represent an message send node.!
@@ -293,6 +293,14 @@ isSideEffect
 	^ isSideEffect ifNil: [ false ]
 !
 
+javaScriptSelector
+	^ javaScriptSelector
+!
+
+javaScriptSelector: aString
+	javaScriptSelector := aString
+!
+
 navigationLink
 	^ self selector
 !

+ 6 - 172
lang/src/Compiler-IR.js

@@ -863,11 +863,11 @@ selector: "visitSendNode:",
 protocol: "visiting",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aNode"],
-source: "visitSendNode: aNode\x0a\x09| send |\x0a\x09send := IRSend new.\x0a\x09send\x0a\x09\x09selector: aNode selector;\x0a\x09\x09index: aNode index.\x0a\x09\x0a\x09(self aliasTemporally: aNode dagChildren) do: [ :each | send add: each ].\x0a\x0a\x09^ send",
+source: "visitSendNode: aNode\x0a\x09| send |\x0a\x09send := IRSend new.\x0a\x09send\x0a\x09\x09selector: aNode selector;\x0a\x09\x09javaScriptSelector: aNode javaScriptSelector;\x0a\x09\x09index: aNode index.\x0a\x09\x0a\x09(self aliasTemporally: aNode dagChildren) do: [ :each | send add: each ].\x0a\x0a\x09^ send",
 referencedClasses: ["IRSend"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "selector:", "selector", "index:", "index", "do:", "aliasTemporally:", "dagChildren", "add:"]
+messageSends: ["new", "selector:", "selector", "javaScriptSelector:", "javaScriptSelector", "index:", "index", "do:", "aliasTemporally:", "dagChildren", "add:"]
 }, function ($methodClass){ return function (aNode){
 var self=this,$self=this;
 var send;
@@ -878,6 +878,7 @@ var $1;
 send=$recv($globals.IRSend)._new();
 $1=send;
 $recv($1)._selector_($recv(aNode)._selector());
+$recv($1)._javaScriptSelector_($recv(aNode)._javaScriptSelector());
 $recv($1)._index_($recv(aNode)._index());
 $recv($self._aliasTemporally_($recv(aNode)._dagChildren()))._do_((function(each){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -3323,24 +3324,16 @@ selector: "jsOverride:",
 protocol: "pragmas",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aString"],
-source: "jsOverride: aString\x0a\x09(IRJSSuperSendVisitor new property: aString; yourself)\x0a\x09\x09visit: self irMethod.\x0a\x09self irMethod attachments\x0a\x09\x09at: aString\x0a\x09\x09put: (NativeFunction\x0a\x09\x09\x09constructorNamed: #Function\x0a\x09\x09\x09value: 'return this.', irMethod selector asJavaScriptMethodName, '()')",
-referencedClasses: ["IRJSSuperSendVisitor", "NativeFunction"],
+source: "jsOverride: aString\x0a\x09self irMethod attachments\x0a\x09\x09at: aString\x0a\x09\x09put: (NativeFunction\x0a\x09\x09\x09constructorNamed: #Function\x0a\x09\x09\x09value: 'return this.', irMethod selector asJavaScriptMethodName, '()')",
+referencedClasses: ["NativeFunction"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["visit:", "property:", "new", "yourself", "irMethod", "at:put:", "attachments", "constructorNamed:value:", ",", "asJavaScriptMethodName", "selector"]
+messageSends: ["at:put:", "attachments", "irMethod", "constructorNamed:value:", ",", "asJavaScriptMethodName", "selector"]
 }, function ($methodClass){ return function (aString){
 var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $1;
-$1=$recv($globals.IRJSSuperSendVisitor)._new();
-$recv($1)._property_(aString);
-$recv($recv($1)._yourself())._visit_([$self._irMethod()
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["irMethod"]=1
-//>>excludeEnd("ctx");
-][0]);
 $recv($recv($self._irMethod())._attachments())._at_put_(aString,$recv($globals.NativeFunction)._constructorNamed_value_("Function",[$recv("return this.".__comma($recv($recv($self.irMethod)._selector())._asJavaScriptMethodName())).__comma("()")
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 ,$ctx1.sendIdx[","]=1
@@ -3749,165 +3742,6 @@ $globals.IRVisitor);
 
 
 
-$core.addClass("IRJSSuperSendVisitor", $globals.IRVisitor, ["selector", "property"], "Compiler-IR");
-$core.addMethod(
-$core.method({
-selector: "property",
-protocol: "accessing",
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "property\x0a\x09^ property",
-referencedClasses: [],
-//>>excludeEnd("ide");
-pragmas: [],
-messageSends: []
-}, function ($methodClass){ return function (){
-var self=this,$self=this;
-return $self.property;
-
-}; }),
-$globals.IRJSSuperSendVisitor);
-
-$core.addMethod(
-$core.method({
-selector: "property:",
-protocol: "accessing",
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anObject"],
-source: "property: anObject\x0a\x09property := anObject",
-referencedClasses: [],
-//>>excludeEnd("ide");
-pragmas: [],
-messageSends: []
-}, function ($methodClass){ return function (anObject){
-var self=this,$self=this;
-$self.property=anObject;
-return self;
-
-}; }),
-$globals.IRJSSuperSendVisitor);
-
-$core.addMethod(
-$core.method({
-selector: "selector",
-protocol: "accessing",
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "selector\x0a\x09^ selector",
-referencedClasses: [],
-//>>excludeEnd("ide");
-pragmas: [],
-messageSends: []
-}, function ($methodClass){ return function (){
-var self=this,$self=this;
-return $self.selector;
-
-}; }),
-$globals.IRJSSuperSendVisitor);
-
-$core.addMethod(
-$core.method({
-selector: "selector:",
-protocol: "accessing",
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anObject"],
-source: "selector: anObject\x0a\x09selector := anObject",
-referencedClasses: [],
-//>>excludeEnd("ide");
-pragmas: [],
-messageSends: []
-}, function ($methodClass){ return function (anObject){
-var self=this,$self=this;
-$self.selector=anObject;
-return self;
-
-}; }),
-$globals.IRJSSuperSendVisitor);
-
-$core.addMethod(
-$core.method({
-selector: "visitIRMethod:",
-protocol: "accessing",
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anIRMethod"],
-source: "visitIRMethod: anIRMethod\x0a\x09self selector: anIRMethod selector.\x0a\x09^ super visitIRMethod: anIRMethod",
-referencedClasses: [],
-//>>excludeEnd("ide");
-pragmas: [],
-messageSends: ["selector:", "selector", "visitIRMethod:"]
-}, function ($methodClass){ return function (anIRMethod){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-$self._selector_($recv(anIRMethod)._selector());
-return [(
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.supercall = true,
-//>>excludeEnd("ctx");
-($methodClass.superclass||$boot.nilAsClass).fn.prototype._visitIRMethod_.call($self,anIRMethod))
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.supercall = false
-//>>excludeEnd("ctx");
-][0];
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"visitIRMethod:",{anIRMethod:anIRMethod})});
-//>>excludeEnd("ctx");
-}; }),
-$globals.IRJSSuperSendVisitor);
-
-$core.addMethod(
-$core.method({
-selector: "visitIRSend:",
-protocol: "accessing",
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anIRSend"],
-source: "visitIRSend: anIRSend\x0a\x09| receiver |\x0a\x09receiver := anIRSend receiver.\x0a\x09receiver isSuper ifTrue: [\x0a\x09\x09anIRSend selector = self selector ifTrue: [\x0a\x09\x09\x09| old |\x0a\x09\x09\x09old := receiver variable.\x0a\x09\x09\x09receiver variable: (\x0a\x09\x09\x09\x09JavaScriptSuperVar new\x0a\x09\x09\x09\x09\x09scope: old scope;\x0a\x09\x09\x09\x09\x09name: old name;\x0a\x09\x09\x09\x09\x09yourself ).\x0a\x09\x09\x09anIRSend javaScriptSelector: self property ] ].\x0a\x09^ super visitIRSend: anIRSend",
-referencedClasses: ["JavaScriptSuperVar"],
-//>>excludeEnd("ide");
-pragmas: [],
-messageSends: ["receiver", "ifTrue:", "isSuper", "=", "selector", "variable", "variable:", "scope:", "new", "scope", "name:", "name", "yourself", "javaScriptSelector:", "property", "visitIRSend:"]
-}, function ($methodClass){ return function (anIRSend){
-var self=this,$self=this;
-var receiver;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-var $1,$2;
-receiver=$recv(anIRSend)._receiver();
-if($core.assert($recv(receiver)._isSuper())){
-if($core.assert($recv([$recv(anIRSend)._selector()
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["selector"]=1
-//>>excludeEnd("ctx");
-][0]).__eq($self._selector()))){
-var old;
-old=$recv(receiver)._variable();
-$1=receiver;
-$2=$recv($globals.JavaScriptSuperVar)._new();
-$recv($2)._scope_($recv(old)._scope());
-$recv($2)._name_($recv(old)._name());
-$recv($1)._variable_($recv($2)._yourself());
-$recv(anIRSend)._javaScriptSelector_($self._property());
-}
-}
-return [(
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.supercall = true,
-//>>excludeEnd("ctx");
-($methodClass.superclass||$boot.nilAsClass).fn.prototype._visitIRSend_.call($self,anIRSend))
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.supercall = false
-//>>excludeEnd("ctx");
-][0];
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"visitIRSend:",{anIRSend:anIRSend,receiver:receiver})});
-//>>excludeEnd("ctx");
-}; }),
-$globals.IRJSSuperSendVisitor);
-
-
-
 $core.addClass("IRJSTranslator", $globals.IRVisitor, ["stream", "currentClass"], "Compiler-IR");
 $core.addMethod(
 $core.method({

+ 1 - 45
lang/src/Compiler-IR.st

@@ -218,6 +218,7 @@ visitSendNode: aNode
 	send := IRSend new.
 	send
 		selector: aNode selector;
+		javaScriptSelector: aNode javaScriptSelector;
 		index: aNode index.
 	
 	(self aliasTemporally: aNode dagChildren) do: [ :each | send add: each ].
@@ -871,8 +872,6 @@ IRPragmator subclass: #IRLatePragmator
 !IRLatePragmator methodsFor: 'pragmas'!
 
 jsOverride: aString
-	(IRJSSuperSendVisitor new property: aString; yourself)
-		visit: self irMethod.
 	self irMethod attachments
 		at: aString
 		put: (NativeFunction
@@ -954,49 +953,6 @@ visitIRVerbatim: anIRVerbatim
 	^ self visitDagNode: anIRVerbatim
 ! !
 
-IRVisitor subclass: #IRJSSuperSendVisitor
-	slots: {#selector. #property}
-	package: 'Compiler-IR'!
-
-!IRJSSuperSendVisitor methodsFor: 'accessing'!
-
-property
-	^ property
-!
-
-property: anObject
-	property := anObject
-!
-
-selector
-	^ selector
-!
-
-selector: anObject
-	selector := anObject
-!
-
-visitIRMethod: anIRMethod
-	self selector: anIRMethod selector.
-	^ super visitIRMethod: anIRMethod
-!
-
-visitIRSend: anIRSend
-	| receiver |
-	receiver := anIRSend receiver.
-	receiver isSuper ifTrue: [
-		anIRSend selector = self selector ifTrue: [
-			| old |
-			old := receiver variable.
-			receiver variable: (
-				JavaScriptSuperVar new
-					scope: old scope;
-					name: old name;
-					yourself ).
-			anIRSend javaScriptSelector: self property ] ].
-	^ super visitIRSend: anIRSend
-! !
-
 IRVisitor subclass: #IRJSTranslator
 	slots: {#stream. #currentClass}
 	package: 'Compiler-IR'!

+ 186 - 0
lang/src/Compiler-Semantic.js

@@ -4,6 +4,165 @@ var $pkg = $core.addPackage("Compiler-Semantic");
 $pkg.innerEval = function (expr) { return eval(expr); };
 $pkg.transport = {"type":"amd","amdNamespace":"amber/core"};
 
+$core.addClass("JSSuperSendVisitor", $globals.NodeVisitor, ["selector", "property"], "Compiler-Semantic");
+$core.addMethod(
+$core.method({
+selector: "property",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "property\x0a\x09^ property",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: []
+}, function ($methodClass){ return function (){
+var self=this,$self=this;
+return $self.property;
+
+}; }),
+$globals.JSSuperSendVisitor);
+
+$core.addMethod(
+$core.method({
+selector: "property:",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject"],
+source: "property: anObject\x0a\x09property := anObject",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: []
+}, function ($methodClass){ return function (anObject){
+var self=this,$self=this;
+$self.property=anObject;
+return self;
+
+}; }),
+$globals.JSSuperSendVisitor);
+
+$core.addMethod(
+$core.method({
+selector: "selector",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "selector\x0a\x09^ selector",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: []
+}, function ($methodClass){ return function (){
+var self=this,$self=this;
+return $self.selector;
+
+}; }),
+$globals.JSSuperSendVisitor);
+
+$core.addMethod(
+$core.method({
+selector: "selector:",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject"],
+source: "selector: anObject\x0a\x09selector := anObject",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: []
+}, function ($methodClass){ return function (anObject){
+var self=this,$self=this;
+$self.selector=anObject;
+return self;
+
+}; }),
+$globals.JSSuperSendVisitor);
+
+$core.addMethod(
+$core.method({
+selector: "visitMethodNode:",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aNode"],
+source: "visitMethodNode: aNode\x0a\x09self selector: aNode selector.\x0a\x09^ super visitMethodNode: aNode",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: ["selector:", "selector", "visitMethodNode:"]
+}, function ($methodClass){ return function (aNode){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+$self._selector_($recv(aNode)._selector());
+return [(
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = true,
+//>>excludeEnd("ctx");
+($methodClass.superclass||$boot.nilAsClass).fn.prototype._visitMethodNode_.call($self,aNode))
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx1.supercall = false
+//>>excludeEnd("ctx");
+][0];
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"visitMethodNode:",{aNode:aNode})});
+//>>excludeEnd("ctx");
+}; }),
+$globals.JSSuperSendVisitor);
+
+$core.addMethod(
+$core.method({
+selector: "visitSendNode:",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aNode"],
+source: "visitSendNode: aNode\x0a\x09| receiver |\x0a\x09receiver := aNode receiver.\x0a\x09receiver isSuper ifTrue: [\x0a\x09\x09aNode selector = self selector ifTrue: [\x0a\x09\x09\x09| old |\x0a\x09\x09\x09old := receiver binding.\x0a\x09\x09\x09receiver binding: (\x0a\x09\x09\x09\x09JavaScriptSuperVar new\x0a\x09\x09\x09\x09\x09scope: old scope;\x0a\x09\x09\x09\x09\x09name: old name;\x0a\x09\x09\x09\x09\x09yourself ).\x0a\x09\x09\x09aNode javaScriptSelector: self property ] ].\x0a\x09^ super visitSendNode: aNode",
+referencedClasses: ["JavaScriptSuperVar"],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: ["receiver", "ifTrue:", "isSuper", "=", "selector", "binding", "binding:", "scope:", "new", "scope", "name:", "name", "yourself", "javaScriptSelector:", "property", "visitSendNode:"]
+}, function ($methodClass){ return function (aNode){
+var self=this,$self=this;
+var receiver;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2;
+receiver=$recv(aNode)._receiver();
+if($core.assert($recv(receiver)._isSuper())){
+if($core.assert($recv([$recv(aNode)._selector()
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx1.sendIdx["selector"]=1
+//>>excludeEnd("ctx");
+][0]).__eq($self._selector()))){
+var old;
+old=$recv(receiver)._binding();
+$1=receiver;
+$2=$recv($globals.JavaScriptSuperVar)._new();
+$recv($2)._scope_($recv(old)._scope());
+$recv($2)._name_($recv(old)._name());
+$recv($1)._binding_($recv($2)._yourself());
+$recv(aNode)._javaScriptSelector_($self._property());
+}
+}
+return [(
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = true,
+//>>excludeEnd("ctx");
+($methodClass.superclass||$boot.nilAsClass).fn.prototype._visitSendNode_.call($self,aNode))
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx1.supercall = false
+//>>excludeEnd("ctx");
+][0];
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode,receiver:receiver})});
+//>>excludeEnd("ctx");
+}; }),
+$globals.JSSuperSendVisitor);
+
+
+
 $core.addClass("LexicalScope", $globals.Object, ["node", "instruction", "temps", "args", "outerScope", "blockIndex"], "Compiler-Semantic");
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.LexicalScope.comment="I represent a lexical scope where variable names are associated with ScopeVars\x0aInstances are used for block scopes. Method scopes are instances of MethodLexicalScope.\x0a\x0aI am attached to a ScopeVar and method/block nodes.\x0aEach context (method/closure) get a fresh scope that inherits from its outer scope.";
@@ -2748,4 +2907,31 @@ return self;
 $globals.UnknownVariableError);
 
 
+$core.addMethod(
+$core.method({
+selector: "jsOverride:",
+protocol: "*Compiler-Semantic",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aString"],
+source: "jsOverride: aString\x0a\x09(JSSuperSendVisitor new property: aString; yourself)\x0a\x09\x09visit: self methodNode",
+referencedClasses: ["JSSuperSendVisitor"],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: ["visit:", "property:", "new", "yourself", "methodNode"]
+}, function ($methodClass){ return function (aString){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+$1=$recv($globals.JSSuperSendVisitor)._new();
+$recv($1)._property_(aString);
+$recv($recv($1)._yourself())._visit_($self._methodNode());
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"jsOverride:",{aString:aString})});
+//>>excludeEnd("ctx");
+}; }),
+$globals.AstSemanticPragmator);
+
 });

+ 50 - 0
lang/src/Compiler-Semantic.st

@@ -1,4 +1,47 @@
 Smalltalk createPackage: 'Compiler-Semantic'!
+NodeVisitor subclass: #JSSuperSendVisitor
+	slots: {#selector. #property}
+	package: 'Compiler-Semantic'!
+
+!JSSuperSendVisitor methodsFor: 'accessing'!
+
+property
+	^ property
+!
+
+property: anObject
+	property := anObject
+!
+
+selector
+	^ selector
+!
+
+selector: anObject
+	selector := anObject
+!
+
+visitMethodNode: aNode
+	self selector: aNode selector.
+	^ super visitMethodNode: aNode
+!
+
+visitSendNode: aNode
+	| receiver |
+	receiver := aNode receiver.
+	receiver isSuper ifTrue: [
+		aNode selector = self selector ifTrue: [
+			| old |
+			old := receiver binding.
+			receiver binding: (
+				JavaScriptSuperVar new
+					scope: old scope;
+					name: old name;
+					yourself ).
+			aNode javaScriptSelector: self property ] ].
+	^ super visitSendNode: aNode
+! !
+
 Object subclass: #LexicalScope
 	slots: {#node. #instruction. #temps. #args. #outerScope. #blockIndex}
 	package: 'Compiler-Semantic'!
@@ -703,3 +746,10 @@ variableName: aString
 	variableName := aString
 ! !
 
+!AstSemanticPragmator methodsFor: '*Compiler-Semantic'!
+
+jsOverride: aString
+	(JSSuperSendVisitor new property: aString; yourself)
+		visit: self methodNode
+! !
+