|
@@ -154,37 +154,29 @@ $core.method({
|
|
|
selector: "bindingFor:",
|
|
|
protocol: "accessing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
-args: ["aStringOrNode"],
|
|
|
-source: "bindingFor: aStringOrNode\x0a\x09^ self pseudoVars at: aStringOrNode value ifAbsent: [\x0a\x09\x09self args at: aStringOrNode value ifAbsent: [\x0a\x09\x09\x09self temps at: aStringOrNode value ifAbsent: [ nil ]]]",
|
|
|
+args: ["aNode"],
|
|
|
+source: "bindingFor: aNode\x0a\x09| identifier |\x0a\x09identifier := aNode value.\x0a\x09^ self pseudoVars at: identifier ifAbsent: [\x0a\x09\x09self args at: identifier ifAbsent: [\x0a\x09\x09\x09self temps at: identifier ifAbsent: [ nil ]]]",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
|
-messageSends: ["at:ifAbsent:", "pseudoVars", "value", "args", "temps"]
|
|
|
-}, function ($methodClass){ return function (aStringOrNode){
|
|
|
+messageSends: ["value", "at:ifAbsent:", "pseudoVars", "args", "temps"]
|
|
|
+}, function ($methodClass){ return function (aNode){
|
|
|
var self=this,$self=this;
|
|
|
+var identifier;
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
return $core.withContext(function($ctx1) {
|
|
|
//>>excludeEnd("ctx");
|
|
|
-var $2,$3,$4,$5,$1;
|
|
|
-$2=$self._pseudoVars();
|
|
|
-$3=$recv(aStringOrNode)._value();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["value"]=1;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$1=$recv($2)._at_ifAbsent_($3,(function(){
|
|
|
+var $1;
|
|
|
+identifier=$recv(aNode)._value();
|
|
|
+$1=$recv($self._pseudoVars())._at_ifAbsent_(identifier,(function(){
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
return $core.withContext(function($ctx2) {
|
|
|
//>>excludeEnd("ctx");
|
|
|
-$4=$self._args();
|
|
|
-$5=$recv(aStringOrNode)._value();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx2.sendIdx["value"]=2;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-return $recv($4)._at_ifAbsent_($5,(function(){
|
|
|
+return $recv($self._args())._at_ifAbsent_(identifier,(function(){
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
return $core.withContext(function($ctx3) {
|
|
|
//>>excludeEnd("ctx");
|
|
|
-return $recv($self._temps())._at_ifAbsent_($recv(aStringOrNode)._value(),(function(){
|
|
|
+return $recv($self._temps())._at_ifAbsent_(identifier,(function(){
|
|
|
return nil;
|
|
|
|
|
|
}));
|
|
@@ -204,7 +196,7 @@ $ctx1.sendIdx["at:ifAbsent:"]=1;
|
|
|
//>>excludeEnd("ctx");
|
|
|
return $1;
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-}, function($ctx1) {$ctx1.fill(self,"bindingFor:",{aStringOrNode:aStringOrNode})});
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"bindingFor:",{aNode:aNode,identifier:identifier})});
|
|
|
//>>excludeEnd("ctx");
|
|
|
}; }),
|
|
|
$globals.LexicalScope);
|
|
@@ -650,7 +642,7 @@ $globals.LexicalScope);
|
|
|
|
|
|
|
|
|
|
|
|
-$core.addClass("MethodLexicalScope", $globals.LexicalScope, ["iVars", "pseudoVars", "unknownVariables", "localReturn", "nonLocalReturns"], "Compiler-Semantic");
|
|
|
+$core.addClass("MethodLexicalScope", $globals.LexicalScope, ["iVars", "pseudoVars", "localReturn", "nonLocalReturns"], "Compiler-Semantic");
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
$globals.MethodLexicalScope.comment="I represent a method scope.";
|
|
|
//>>excludeEnd("ide");
|
|
@@ -1056,36 +1048,6 @@ return self;
|
|
|
}; }),
|
|
|
$globals.MethodLexicalScope);
|
|
|
|
|
|
-$core.addMethod(
|
|
|
-$core.method({
|
|
|
-selector: "unknownVariables",
|
|
|
-protocol: "accessing",
|
|
|
-//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
-args: [],
|
|
|
-source: "unknownVariables\x0a\x09^ unknownVariables ifNil: [ unknownVariables := OrderedCollection new ]",
|
|
|
-referencedClasses: ["OrderedCollection"],
|
|
|
-//>>excludeEnd("ide");
|
|
|
-pragmas: [],
|
|
|
-messageSends: ["ifNil:", "new"]
|
|
|
-}, function ($methodClass){ return function (){
|
|
|
-var self=this,$self=this;
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-return $core.withContext(function($ctx1) {
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-var $1,$receiver;
|
|
|
-$1=$self.unknownVariables;
|
|
|
-if(($receiver = $1) == null || $receiver.a$nil){
|
|
|
-$self.unknownVariables=$recv($globals.OrderedCollection)._new();
|
|
|
-return $self.unknownVariables;
|
|
|
-} else {
|
|
|
-return $1;
|
|
|
-}
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-}, function($ctx1) {$ctx1.fill(self,"unknownVariables",{})});
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-}; }),
|
|
|
-$globals.MethodLexicalScope);
|
|
|
-
|
|
|
|
|
|
|
|
|
$core.addClass("ScopeVar", $globals.Object, ["scope", "name"], "Compiler-Semantic");
|
|
@@ -1153,11 +1115,11 @@ $globals.ScopeVar);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isImmutable",
|
|
|
+selector: "isExternallyKnownVar",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: [],
|
|
|
-source: "isImmutable\x0a\x09^ false",
|
|
|
+source: "isExternallyKnownVar\x0a\x09^ false",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
@@ -1171,11 +1133,11 @@ $globals.ScopeVar);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isInstanceVar",
|
|
|
+selector: "isImmutable",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: [],
|
|
|
-source: "isInstanceVar\x0a\x09^ false",
|
|
|
+source: "isImmutable\x0a\x09^ false",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
@@ -1189,11 +1151,11 @@ $globals.ScopeVar);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isPseudoVar",
|
|
|
+selector: "isInstanceVar",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: [],
|
|
|
-source: "isPseudoVar\x0a\x09^ false",
|
|
|
+source: "isInstanceVar\x0a\x09^ false",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
@@ -1207,11 +1169,11 @@ $globals.ScopeVar);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isSelf",
|
|
|
+selector: "isPseudoVar",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: [],
|
|
|
-source: "isSelf\x0a\x09^ false",
|
|
|
+source: "isPseudoVar\x0a\x09^ false",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
@@ -1225,11 +1187,11 @@ $globals.ScopeVar);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isSuper",
|
|
|
+selector: "isSelf",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: [],
|
|
|
-source: "isSuper\x0a\x09^ false",
|
|
|
+source: "isSelf\x0a\x09^ false",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
@@ -1243,11 +1205,11 @@ $globals.ScopeVar);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isTempVar",
|
|
|
+selector: "isSuper",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: [],
|
|
|
-source: "isTempVar\x0a\x09^ false",
|
|
|
+source: "isSuper\x0a\x09^ false",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
@@ -1261,11 +1223,11 @@ $globals.ScopeVar);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isUnknownVar",
|
|
|
+selector: "isTempVar",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: [],
|
|
|
-source: "isUnknownVar\x0a\x09^ false",
|
|
|
+source: "isTempVar\x0a\x09^ false",
|
|
|
referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
@@ -1585,6 +1547,30 @@ $globals.ClassRefVar);
|
|
|
|
|
|
|
|
|
|
|
|
+$core.addClass("ExternallyKnownVar", $globals.ScopeVar, [], "Compiler-Semantic");
|
|
|
+//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
+$globals.ExternallyKnownVar.comment="I am a variable known externally (not in method scope).";
|
|
|
+//>>excludeEnd("ide");
|
|
|
+$core.addMethod(
|
|
|
+$core.method({
|
|
|
+selector: "isExternallyKnownVar",
|
|
|
+protocol: "testing",
|
|
|
+//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
+args: [],
|
|
|
+source: "isExternallyKnownVar\x0a\x09^ true",
|
|
|
+referencedClasses: [],
|
|
|
+//>>excludeEnd("ide");
|
|
|
+pragmas: [],
|
|
|
+messageSends: []
|
|
|
+}, function ($methodClass){ return function (){
|
|
|
+var self=this,$self=this;
|
|
|
+return true;
|
|
|
+
|
|
|
+}; }),
|
|
|
+$globals.ExternallyKnownVar);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
$core.addClass("InstanceVar", $globals.ScopeVar, [], "Compiler-Semantic");
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
$globals.InstanceVar.comment="I am an instance variable of a method or block.";
|
|
@@ -1881,34 +1867,66 @@ $globals.TempVar);
|
|
|
|
|
|
|
|
|
|
|
|
-$core.addClass("UnknownVar", $globals.ScopeVar, [], "Compiler-Semantic");
|
|
|
+$core.addClass("SemanticAnalyzer", $globals.NodeVisitor, ["currentScope", "blockIndex", "thePackage", "theClass", "classReferences", "messageSends"], "Compiler-Semantic");
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
-$globals.UnknownVar.comment="I am an unknown variable. Amber uses unknown variables as JavaScript globals";
|
|
|
+$globals.SemanticAnalyzer.comment="I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes.";
|
|
|
//>>excludeEnd("ide");
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isUnknownVar",
|
|
|
-protocol: "testing",
|
|
|
+selector: "bindUnscopedVariable:",
|
|
|
+protocol: "private",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
-args: [],
|
|
|
-source: "isUnknownVar\x0a\x09^ true",
|
|
|
-referencedClasses: [],
|
|
|
+args: ["aString"],
|
|
|
+source: "bindUnscopedVariable: aString\x0a\x09aString isCapitalized ifTrue: [ \x22Capital letter variables might be globals.\x22\x0a\x09\x09self classReferences add: aString.\x0a\x09\x09^ ClassRefVar new name: aString; yourself ].\x0a\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a\x09We allow all variables listed by Smalltalk>>#globalJsVariables.\x0a\x09This list includes: `window`, `document`, `process` and `global`\x0a\x09for nodejs and browser environments.\x0a\x09\x0a\x09This is only to make sure compilation works on both browser-based and nodejs environments.\x0a\x09The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09((Smalltalk globalJsVariables includes: aString)\x0a\x09\x09or: [ self isVariableKnown: aString inPackage: self thePackage ]) ifTrue: [\x0a\x09\x09\x09^ ExternallyKnownVar new name: aString; yourself ].\x0a\x0a\x09self errorUnknownVariable: aString",
|
|
|
+referencedClasses: ["ClassRefVar", "Smalltalk", "ExternallyKnownVar"],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
|
-messageSends: []
|
|
|
-}, function ($methodClass){ return function (){
|
|
|
+messageSends: ["ifTrue:", "isCapitalized", "add:", "classReferences", "name:", "new", "yourself", "or:", "includes:", "globalJsVariables", "isVariableKnown:inPackage:", "thePackage", "errorUnknownVariable:"]
|
|
|
+}, function ($methodClass){ return function (aString){
|
|
|
var self=this,$self=this;
|
|
|
-return true;
|
|
|
-
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+return $core.withContext(function($ctx1) {
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+var $1,$2,$3,$4,$5;
|
|
|
+$1=$recv(aString)._isCapitalized();
|
|
|
+if($core.assert($1)){
|
|
|
+$recv($self._classReferences())._add_(aString);
|
|
|
+$2=$recv($globals.ClassRefVar)._new();
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+$ctx1.sendIdx["new"]=1;
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+$recv($2)._name_(aString);
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+$ctx1.sendIdx["name:"]=1;
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+$3=$recv($2)._yourself();
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+$ctx1.sendIdx["yourself"]=1;
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+return $3;
|
|
|
+}
|
|
|
+$4=$recv($recv($recv($globals.Smalltalk)._globalJsVariables())._includes_(aString))._or_((function(){
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+return $core.withContext(function($ctx2) {
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+return $self._isVariableKnown_inPackage_(aString,$self._thePackage());
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)});
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+}));
|
|
|
+if($core.assert($4)){
|
|
|
+$5=$recv($globals.ExternallyKnownVar)._new();
|
|
|
+$recv($5)._name_(aString);
|
|
|
+return $recv($5)._yourself();
|
|
|
+}
|
|
|
+$self._errorUnknownVariable_(aString);
|
|
|
+return self;
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"bindUnscopedVariable:",{aString:aString})});
|
|
|
+//>>excludeEnd("ctx");
|
|
|
}; }),
|
|
|
-$globals.UnknownVar);
|
|
|
-
|
|
|
-
|
|
|
+$globals.SemanticAnalyzer);
|
|
|
|
|
|
-$core.addClass("SemanticAnalyzer", $globals.NodeVisitor, ["currentScope", "blockIndex", "thePackage", "theClass", "classReferences", "messageSends"], "Compiler-Semantic");
|
|
|
-//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
-$globals.SemanticAnalyzer.comment="I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes.";
|
|
|
-//>>excludeEnd("ide");
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
selector: "classReferences",
|
|
@@ -1971,84 +1989,61 @@ $core.method({
|
|
|
selector: "errorUnknownVariable:",
|
|
|
protocol: "error handling",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
-args: ["aNode"],
|
|
|
-source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a\x09We allow all variables listed by Smalltalk>>#globalJsVariables.\x0a\x09This list includes: `window`, `document`, `process` and `global`\x0a\x09for nodejs and browser environments.\x0a\x09\x0a\x09This is only to make sure compilation works on both browser-based and nodejs environments.\x0a\x09The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09| identifier |\x0a\x09identifier := aNode value.\x0a\x09\x0a\x09((Smalltalk globalJsVariables includes: identifier) not\x0a\x09\x09and: [ self isVariableUndefined: identifier inPackage: self thePackage ])\x0a\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09UnknownVariableError new\x0a\x09\x09\x09\x09\x09variableName: aNode value;\x0a\x09\x09\x09\x09\x09signal ]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09currentScope methodScope unknownVariables add: aNode value ]",
|
|
|
-referencedClasses: ["Smalltalk", "UnknownVariableError"],
|
|
|
+args: ["aString"],
|
|
|
+source: "errorUnknownVariable: aString\x0a\x09UnknownVariableError new\x0a\x09\x09variableName: aString;\x0a\x09\x09signal",
|
|
|
+referencedClasses: ["UnknownVariableError"],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
|
-messageSends: ["value", "ifTrue:ifFalse:", "and:", "not", "includes:", "globalJsVariables", "isVariableUndefined:inPackage:", "thePackage", "variableName:", "new", "signal", "add:", "unknownVariables", "methodScope"]
|
|
|
-}, function ($methodClass){ return function (aNode){
|
|
|
+messageSends: ["variableName:", "new", "signal"]
|
|
|
+}, function ($methodClass){ return function (aString){
|
|
|
var self=this,$self=this;
|
|
|
-var identifier;
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
return $core.withContext(function($ctx1) {
|
|
|
//>>excludeEnd("ctx");
|
|
|
-var $1,$2,$3;
|
|
|
-identifier=$recv(aNode)._value();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["value"]=1;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$1=$recv($recv($recv($recv($globals.Smalltalk)._globalJsVariables())._includes_(identifier))._not())._and_((function(){
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-return $core.withContext(function($ctx2) {
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-return $self._isVariableUndefined_inPackage_(identifier,$self._thePackage());
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-}));
|
|
|
-if($core.assert($1)){
|
|
|
-$2=$recv($globals.UnknownVariableError)._new();
|
|
|
-$3=$recv(aNode)._value();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["value"]=2;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$recv($2)._variableName_($3);
|
|
|
-$recv($2)._signal();
|
|
|
-} else {
|
|
|
-$recv($recv($recv($self.currentScope)._methodScope())._unknownVariables())._add_($recv(aNode)._value());
|
|
|
-}
|
|
|
+var $1;
|
|
|
+$1=$recv($globals.UnknownVariableError)._new();
|
|
|
+$recv($1)._variableName_(aString);
|
|
|
+$recv($1)._signal();
|
|
|
return self;
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-}, function($ctx1) {$ctx1.fill(self,"errorUnknownVariable:",{aNode:aNode,identifier:identifier})});
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"errorUnknownVariable:",{aString:aString})});
|
|
|
//>>excludeEnd("ctx");
|
|
|
}; }),
|
|
|
$globals.SemanticAnalyzer);
|
|
|
|
|
|
$core.addMethod(
|
|
|
$core.method({
|
|
|
-selector: "isVariableUndefined:inPackage:",
|
|
|
+selector: "isVariableKnown:inPackage:",
|
|
|
protocol: "testing",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: ["aString", "aPackage"],
|
|
|
-source: "isVariableUndefined: aString inPackage: aPackage\x0a\x09aPackage ifNotNil: [\x0a\x09\x09| packageKnownVars |\x0a\x09\x09packageKnownVars := (aPackage imports\x0a\x09\x09\x09reject: #isString)\x0a\x09\x09\x09collect: #key.\x0a\x09\x09(packageKnownVars includes: aString) ifTrue: [ ^ false ]].\x0a\x09^ Compiler eval: 'typeof ', aString, ' === \x22undefined\x22'",
|
|
|
+source: "isVariableKnown: aString inPackage: aPackage\x0a\x09^ Compiler new\x0a\x09\x09eval: 'typeof(', aString, ')!== \x22undefined\x22||(function(){try{return(', aString, ',true)}catch(_){return false}})()'\x0a\x09\x09forPackage: aPackage",
|
|
|
referencedClasses: ["Compiler"],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
|
-messageSends: ["ifNotNil:", "collect:", "reject:", "imports", "ifTrue:", "includes:", "eval:", ","]
|
|
|
+messageSends: ["eval:forPackage:", "new", ","]
|
|
|
}, function ($methodClass){ return function (aString,aPackage){
|
|
|
var self=this,$self=this;
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
return $core.withContext(function($ctx1) {
|
|
|
//>>excludeEnd("ctx");
|
|
|
-var $1,$2,$receiver;
|
|
|
-if(($receiver = aPackage) == null || $receiver.a$nil){
|
|
|
-aPackage;
|
|
|
-} else {
|
|
|
-var packageKnownVars;
|
|
|
-packageKnownVars=$recv($recv($recv(aPackage)._imports())._reject_("isString"))._collect_("key");
|
|
|
-$1=$recv(packageKnownVars)._includes_(aString);
|
|
|
-if($core.assert($1)){
|
|
|
-return false;
|
|
|
-}
|
|
|
-}
|
|
|
-$2=$recv("typeof ".__comma(aString)).__comma(" === \x22undefined\x22");
|
|
|
+var $1,$4,$3,$2;
|
|
|
+$1=$recv($globals.Compiler)._new();
|
|
|
+$4=$recv("typeof(".__comma(aString)).__comma(")!== \x22undefined\x22||(function(){try{return(");
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+$ctx1.sendIdx[","]=3;
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+$3=$recv($4).__comma(aString);
|
|
|
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
+$ctx1.sendIdx[","]=2;
|
|
|
+//>>excludeEnd("ctx");
|
|
|
+$2=$recv($3).__comma(",true)}catch(_){return false}})()");
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
$ctx1.sendIdx[","]=1;
|
|
|
//>>excludeEnd("ctx");
|
|
|
-return $recv($globals.Compiler)._eval_($2);
|
|
|
+return $recv($1)._eval_forPackage_($2,aPackage);
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-}, function($ctx1) {$ctx1.fill(self,"isVariableUndefined:inPackage:",{aString:aString,aPackage:aPackage})});
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"isVariableKnown:inPackage:",{aString:aString,aPackage:aPackage})});
|
|
|
//>>excludeEnd("ctx");
|
|
|
}; }),
|
|
|
$globals.SemanticAnalyzer);
|
|
@@ -2645,63 +2640,27 @@ selector: "visitVariableNode:",
|
|
|
protocol: "visiting",
|
|
|
//>>excludeStart("ide", pragmas.excludeIdeData);
|
|
|
args: ["aNode"],
|
|
|
-source: "visitVariableNode: aNode\x0a\x09\x22Bind a ScopeVar to aNode by doing a lookup in the current scope.\x0a\x09If no ScopeVar is found, bind a UnknowVar and throw an error.\x22\x0a\x0a\x09| binding |\x0a\x09binding := currentScope lookupVariable: aNode.\x0a\x09\x0a\x09binding ifNil: [\x0a\x09\x09aNode value isCapitalized\x0a\x09\x09\x09ifTrue: [ \x22Capital letter variables might be globals.\x22\x0a\x09\x09\x09\x09binding := ClassRefVar new name: aNode value; yourself.\x0a\x09\x09\x09\x09self classReferences add: aNode value]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09self errorUnknownVariable: aNode.\x0a\x09\x09\x09\x09binding := UnknownVar new name: aNode value; yourself ] ].\x0a\x09\x09\x0a\x09aNode binding: binding.",
|
|
|
-referencedClasses: ["ClassRefVar", "UnknownVar"],
|
|
|
+source: "visitVariableNode: aNode\x0a\x09\x22Bind a ScopeVar to aNode by doing a lookup in the current scope.\x0a\x09If no var is found in scope, represent an externally known variable or throw an error.\x22\x0a\x0a\x09aNode binding:\x0a\x09\x09((currentScope lookupVariable: aNode) ifNil: [ self bindUnscopedVariable: aNode value ])",
|
|
|
+referencedClasses: [],
|
|
|
//>>excludeEnd("ide");
|
|
|
pragmas: [],
|
|
|
-messageSends: ["lookupVariable:", "ifNil:", "ifTrue:ifFalse:", "isCapitalized", "value", "name:", "new", "yourself", "add:", "classReferences", "errorUnknownVariable:", "binding:"]
|
|
|
+messageSends: ["binding:", "ifNil:", "lookupVariable:", "bindUnscopedVariable:", "value"]
|
|
|
}, function ($methodClass){ return function (aNode){
|
|
|
var self=this,$self=this;
|
|
|
-var binding;
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
return $core.withContext(function($ctx1) {
|
|
|
//>>excludeEnd("ctx");
|
|
|
-var $1,$3,$2,$4,$5,$6,$7,$8,$receiver;
|
|
|
-binding=$recv($self.currentScope)._lookupVariable_(aNode);
|
|
|
-$1=binding;
|
|
|
-if(($receiver = $1) == null || $receiver.a$nil){
|
|
|
-$3=$recv(aNode)._value();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["value"]=1;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$2=$recv($3)._isCapitalized();
|
|
|
-if($core.assert($2)){
|
|
|
-$4=$recv($globals.ClassRefVar)._new();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["new"]=1;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$5=$recv(aNode)._value();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["value"]=2;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$recv($4)._name_($5);
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["name:"]=1;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-binding=$recv($4)._yourself();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["yourself"]=1;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$6=$self._classReferences();
|
|
|
-$7=$recv(aNode)._value();
|
|
|
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-$ctx1.sendIdx["value"]=3;
|
|
|
-//>>excludeEnd("ctx");
|
|
|
-$recv($6)._add_($7);
|
|
|
-} else {
|
|
|
-$self._errorUnknownVariable_(aNode);
|
|
|
-$8=$recv($globals.UnknownVar)._new();
|
|
|
-$recv($8)._name_($recv(aNode)._value());
|
|
|
-binding=$recv($8)._yourself();
|
|
|
-binding;
|
|
|
-}
|
|
|
+var $2,$1,$receiver;
|
|
|
+$2=$recv($self.currentScope)._lookupVariable_(aNode);
|
|
|
+if(($receiver = $2) == null || $receiver.a$nil){
|
|
|
+$1=$self._bindUnscopedVariable_($recv(aNode)._value());
|
|
|
} else {
|
|
|
-$1;
|
|
|
+$1=$2;
|
|
|
}
|
|
|
-$recv(aNode)._binding_(binding);
|
|
|
+$recv(aNode)._binding_($1);
|
|
|
return self;
|
|
|
//>>excludeStart("ctx", pragmas.excludeDebugContexts);
|
|
|
-}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode,binding:binding})});
|
|
|
+}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode})});
|
|
|
//>>excludeEnd("ctx");
|
|
|
}; }),
|
|
|
$globals.SemanticAnalyzer);
|