Browse Source

compiler: imports in define call enclosed in pragma

Herbert Vojčík 9 years ago
parent
commit
14f05fc645
2 changed files with 156 additions and 41 deletions
  1. 125 31
      src/Kernel-ImportExport.js
  2. 31 10
      src/Kernel-ImportExport.st

+ 125 - 31
src/Kernel-ImportExport.js

@@ -1954,36 +1954,62 @@ selector: "exportPackagePrologueOf:on:",
 protocol: 'output',
 protocol: 'output',
 fn: function (aPackage,aStream){
 fn: function (aPackage,aStream){
 var self=this;
 var self=this;
-var namedImports,anonImports,importVarNames,loadDependencies;
+var importsForOutput,loadDependencies,pragmaStart,pragmaEnd;
+function $String(){return $globals.String||(typeof String=="undefined"?nil:String)}
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-var $1,$5,$4,$3,$2,$6;
-namedImports=[];
-anonImports=[];
-importVarNames=[];
-$recv($recv(aPackage)._imports())._do_((function(each){
+var $1,$3,$2,$4,$6,$5,$7,$13,$12,$11,$10,$9,$8,$17,$16,$15,$14,$18;
+pragmaStart="";
+pragmaEnd="";
+importsForOutput=self._importsForOutput_(aPackage);
+loadDependencies=self._amdNamesOfPackages_($recv(aPackage)._loadDependencies());
+$1=$recv(importsForOutput)._value();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["value"]=1;
+//>>excludeEnd("ctx");
+$recv($1)._ifNotEmpty_((function(){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx2) {
 return $core.withContext(function($ctx2) {
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$1=$recv(each)._isString();
-if($core.assert($1)){
-return $recv(anonImports)._add_(each);
+$3=$recv($String())._lf();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx2.sendIdx["add:"]=1;
+$ctx2.sendIdx["lf"]=1;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-} else {
-$recv(namedImports)._add_($recv(each)._value());
+$2=$recv($3).__comma("//>>excludeStart(\x22imports\x22, pragmas.excludeImports);");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx2.sendIdx["add:"]=2;
+$ctx2.sendIdx[","]=2;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-return $recv(importVarNames)._add_($recv(each)._key());
-};
+$4=$recv($String())._lf();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
+$ctx2.sendIdx["lf"]=2;
+//>>excludeEnd("ctx");
+pragmaStart=$recv($2).__comma($4);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx[","]=1;
+//>>excludeEnd("ctx");
+pragmaStart;
+$6=$recv($String())._lf();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["lf"]=3;
+//>>excludeEnd("ctx");
+$5=$recv($6).__comma("//>>excludeEnd(\x22imports\x22);");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx[","]=4;
+//>>excludeEnd("ctx");
+$7=$recv($String())._lf();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["lf"]=4;
+//>>excludeEnd("ctx");
+pragmaEnd=$recv($5).__comma($7);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx[","]=3;
+//>>excludeEnd("ctx");
+return pragmaEnd;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 }));
 }));
-loadDependencies=self._amdNamesOfPackages_($recv(aPackage)._loadDependencies());
 $recv(aStream)._nextPutAll_("define(\x22");
 $recv(aStream)._nextPutAll_("define(\x22");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=1;
 $ctx1.sendIdx["nextPutAll:"]=1;
@@ -2004,20 +2030,28 @@ $recv(aStream)._nextPutAll_("\x22, ");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=5;
 $ctx1.sendIdx["nextPutAll:"]=5;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$5=["amber/boot"].__comma(namedImports);
+$13=["amber/boot", ":1:"].__comma($recv(importsForOutput)._value());
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx[","]=3;
+$ctx1.sendIdx[","]=7;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$4=$recv($5).__comma(anonImports);
+$12=$recv($13).__comma([":2:"]);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx[","]=2;
+$ctx1.sendIdx[","]=6;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$3=$recv($4).__comma(loadDependencies);
+$11=$recv($12).__comma(loadDependencies);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx[","]=1;
+$ctx1.sendIdx[","]=5;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$2=$recv($3)._asJavascript();
-$recv(aStream)._nextPutAll_($2);
+$10=$recv($11)._asJavascript();
+$9=$recv($10)._replace_with_(",\x5cs*[\x22']:1:[\x22']",pragmaStart);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["replace:with:"]=2;
+//>>excludeEnd("ctx");
+$8=$recv($9)._replace_with_(",\x5cs*[\x22']:2:[\x22']",pragmaEnd);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["replace:with:"]=1;
+//>>excludeEnd("ctx");
+$recv(aStream)._nextPutAll_($8);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=6;
 $ctx1.sendIdx["nextPutAll:"]=6;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
@@ -2025,7 +2059,17 @@ $recv(aStream)._nextPutAll_(", function(");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=7;
 $ctx1.sendIdx["nextPutAll:"]=7;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$recv(aStream)._nextPutAll_($recv(["$boot"].__comma(importVarNames))._join_(","));
+$17=$recv(["$boot", ":1:"].__comma($recv(importsForOutput)._key())).__comma([":2:"]);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx[","]=8;
+//>>excludeEnd("ctx");
+$16=$recv($17)._join_(",");
+$15=$recv($16)._replace_with_(",\x5cs*:1:",pragmaStart);
+$14=$recv($15)._replace_with_(",\x5cs*:2:",pragmaEnd);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["replace:with:"]=3;
+//>>excludeEnd("ctx");
+$recv(aStream)._nextPutAll_($14);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=8;
 $ctx1.sendIdx["nextPutAll:"]=8;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
@@ -2035,21 +2079,71 @@ $ctx1.sendIdx["nextPutAll:"]=9;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 $recv(aStream)._lf();
 $recv(aStream)._lf();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["lf"]=1;
+$ctx1.sendIdx["lf"]=5;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 $recv(aStream)._nextPutAll_("var $core=$boot.api,nil=$boot.nil,$recv=$boot.asReceiver,$globals=$boot.globals;");
 $recv(aStream)._nextPutAll_("var $core=$boot.api,nil=$boot.nil,$recv=$boot.asReceiver,$globals=$boot.globals;");
-$6=$recv(aStream)._lf();
+$18=$recv(aStream)._lf();
 return self;
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"exportPackagePrologueOf:on:",{aPackage:aPackage,aStream:aStream,namedImports:namedImports,anonImports:anonImports,importVarNames:importVarNames,loadDependencies:loadDependencies},$globals.AmdExporter)});
+}, function($ctx1) {$ctx1.fill(self,"exportPackagePrologueOf:on:",{aPackage:aPackage,aStream:aStream,importsForOutput:importsForOutput,loadDependencies:loadDependencies,pragmaStart:pragmaStart,pragmaEnd:pragmaEnd},$globals.AmdExporter)});
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 },
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aPackage", "aStream"],
 args: ["aPackage", "aStream"],
-source: "exportPackagePrologueOf: aPackage on: aStream\x0a\x09| namedImports anonImports importVarNames loadDependencies |\x0a\x09namedImports := #().\x0a\x09anonImports := #().\x0a\x09importVarNames := #().\x0a\x09aPackage imports do: [ :each | each isString\x0a\x09\x09ifTrue: [ anonImports add: each ]\x0a\x09\x09ifFalse: [ namedImports add: each value.\x0a\x09\x09\x09importVarNames add: each key ]].\x0a\x09loadDependencies := self amdNamesOfPackages: aPackage loadDependencies.\x0a\x09aStream\x0a\x09\x09nextPutAll: 'define(\x22';\x0a\x09\x09nextPutAll: (self amdNamespaceOfPackage: aPackage);\x0a\x09\x09nextPutAll: '/'; \x0a\x09\x09nextPutAll: aPackage name;\x0a\x09\x09nextPutAll: '\x22, ';\x0a\x09\x09nextPutAll: (#('amber/boot'), namedImports, anonImports, loadDependencies) asJavascript;\x0a\x09\x09nextPutAll: ', function(';\x0a\x09\x09nextPutAll: (#('$boot'), importVarNames join: ',');\x0a\x09\x09nextPutAll: '){';\x0a\x09\x09lf;\x0a\x09\x09nextPutAll: 'var $core=$boot.api,nil=$boot.nil,$recv=$boot.asReceiver,$globals=$boot.globals;';\x0a\x09\x09lf",
+source: "exportPackagePrologueOf: aPackage on: aStream\x0a\x09| importsForOutput loadDependencies pragmaStart pragmaEnd |\x0a\x09pragmaStart := ''.\x0a\x09pragmaEnd := ''.\x0a\x09importsForOutput := self importsForOutput: aPackage.\x0a\x09loadDependencies := self amdNamesOfPackages: aPackage loadDependencies.\x0a\x09importsForOutput value ifNotEmpty: [\x0a\x09\x09pragmaStart := String lf, '//>>excludeStart(\x22imports\x22, pragmas.excludeImports);', String lf.\x0a\x09\x09pragmaEnd := String lf, '//>>excludeEnd(\x22imports\x22);', String lf ].\x0a\x09aStream\x0a\x09\x09nextPutAll: 'define(\x22';\x0a\x09\x09nextPutAll: (self amdNamespaceOfPackage: aPackage);\x0a\x09\x09nextPutAll: '/'; \x0a\x09\x09nextPutAll: aPackage name;\x0a\x09\x09nextPutAll: '\x22, ';\x0a\x09\x09nextPutAll: (((\x0a\x09\x09\x09(#('amber/boot' ':1:'), importsForOutput value, #(':2:'), loadDependencies) asJavascript)\x0a\x09\x09\x09replace: ',\x5cs*[\x22'']:1:[\x22'']' with: pragmaStart) replace: ',\x5cs*[\x22'']:2:[\x22'']' with: pragmaEnd);\x0a\x09\x09nextPutAll: ', function(';\x0a\x09\x09nextPutAll: (((\x0a\x09\x09\x09(#('$boot' ':1:'), importsForOutput key, #(':2:')) join: ',')\x0a\x09\x09\x09replace: ',\x5cs*:1:' with: pragmaStart) replace: ',\x5cs*:2:' with: pragmaEnd);\x0a\x09\x09nextPutAll: '){';\x0a\x09\x09lf;\x0a\x09\x09nextPutAll: 'var $core=$boot.api,nil=$boot.nil,$recv=$boot.asReceiver,$globals=$boot.globals;';\x0a\x09\x09lf",
+referencedClasses: ["String"],
+//>>excludeEnd("ide");
+messageSends: ["importsForOutput:", "amdNamesOfPackages:", "loadDependencies", "ifNotEmpty:", "value", ",", "lf", "nextPutAll:", "amdNamespaceOfPackage:", "name", "replace:with:", "asJavascript", "join:", "key"]
+}),
+$globals.AmdExporter);
+
+$core.addMethod(
+$core.method({
+selector: "importsForOutput:",
+protocol: 'private',
+fn: function (aPackage){
+var self=this;
+var namedImports,anonImports,importVarNames;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2;
+namedImports=[];
+anonImports=[];
+importVarNames=[];
+$recv($recv(aPackage)._imports())._do_((function(each){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+$1=$recv(each)._isString();
+if($core.assert($1)){
+return $recv(anonImports)._add_(each);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["add:"]=1;
+//>>excludeEnd("ctx");
+} else {
+$recv(namedImports)._add_($recv(each)._value());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx2.sendIdx["add:"]=2;
+//>>excludeEnd("ctx");
+return $recv(importVarNames)._add_($recv(each)._key());
+};
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+$2=$recv(importVarNames).__minus_gt($recv(namedImports).__comma(anonImports));
+return $2;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"importsForOutput:",{aPackage:aPackage,namedImports:namedImports,anonImports:anonImports,importVarNames:importVarNames},$globals.AmdExporter)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aPackage"],
+source: "importsForOutput: aPackage\x0a\x09\x22Returns an association where key is list of import variables\x0a\x09and value is list of external dependencies, with ones imported as variables\x0a\x09put at the beginning with same order as is in key.\x0a\x09\x0a\x09For example imports:{'jQuery'->'jquery'. 'bootstrap'} would yield\x0a\x09#('jQuery') -> #('jquery' 'bootstrap')\x22\x0a\x09| namedImports anonImports importVarNames |\x0a\x09namedImports := #().\x0a\x09anonImports := #().\x0a\x09importVarNames := #().\x0a\x09aPackage imports do: [ :each | each isString\x0a\x09\x09ifTrue: [ anonImports add: each ]\x0a\x09\x09ifFalse: [ namedImports add: each value.\x0a\x09\x09\x09importVarNames add: each key ]].\x0a\x09^ importVarNames -> (namedImports, anonImports)",
 referencedClasses: [],
 referencedClasses: [],
 //>>excludeEnd("ide");
 //>>excludeEnd("ide");
-messageSends: ["do:", "imports", "ifTrue:ifFalse:", "isString", "add:", "value", "key", "amdNamesOfPackages:", "loadDependencies", "nextPutAll:", "amdNamespaceOfPackage:", "name", "asJavascript", ",", "join:", "lf"]
+messageSends: ["do:", "imports", "ifTrue:ifFalse:", "isString", "add:", "value", "key", "->", ","]
 }),
 }),
 $globals.AmdExporter);
 $globals.AmdExporter);
 
 

+ 31 - 10
src/Kernel-ImportExport.st

@@ -416,24 +416,27 @@ exportPackageEpilogueOf: aPackage on: aStream
 !
 !
 
 
 exportPackagePrologueOf: aPackage on: aStream
 exportPackagePrologueOf: aPackage on: aStream
-	| namedImports anonImports importVarNames loadDependencies |
-	namedImports := #().
-	anonImports := #().
-	importVarNames := #().
-	aPackage imports do: [ :each | each isString
-		ifTrue: [ anonImports add: each ]
-		ifFalse: [ namedImports add: each value.
-			importVarNames add: each key ]].
+	| importsForOutput loadDependencies pragmaStart pragmaEnd |
+	pragmaStart := ''.
+	pragmaEnd := ''.
+	importsForOutput := self importsForOutput: aPackage.
 	loadDependencies := self amdNamesOfPackages: aPackage loadDependencies.
 	loadDependencies := self amdNamesOfPackages: aPackage loadDependencies.
+	importsForOutput value ifNotEmpty: [
+		pragmaStart := String lf, '//>>excludeStart("imports", pragmas.excludeImports);', String lf.
+		pragmaEnd := String lf, '//>>excludeEnd("imports");', String lf ].
 	aStream
 	aStream
 		nextPutAll: 'define("';
 		nextPutAll: 'define("';
 		nextPutAll: (self amdNamespaceOfPackage: aPackage);
 		nextPutAll: (self amdNamespaceOfPackage: aPackage);
 		nextPutAll: '/'; 
 		nextPutAll: '/'; 
 		nextPutAll: aPackage name;
 		nextPutAll: aPackage name;
 		nextPutAll: '", ';
 		nextPutAll: '", ';
-		nextPutAll: (#('amber/boot'), namedImports, anonImports, loadDependencies) asJavascript;
+		nextPutAll: (((
+			(#('amber/boot' ':1:'), importsForOutput value, #(':2:'), loadDependencies) asJavascript)
+			replace: ',\s*["'']:1:["'']' with: pragmaStart) replace: ',\s*["'']:2:["'']' with: pragmaEnd);
 		nextPutAll: ', function(';
 		nextPutAll: ', function(';
-		nextPutAll: (#('$boot'), importVarNames join: ',');
+		nextPutAll: (((
+			(#('$boot' ':1:'), importsForOutput key, #(':2:')) join: ',')
+			replace: ',\s*:1:' with: pragmaStart) replace: ',\s*:2:' with: pragmaEnd);
 		nextPutAll: '){';
 		nextPutAll: '){';
 		lf;
 		lf;
 		nextPutAll: 'var $core=$boot.api,nil=$boot.nil,$recv=$boot.asReceiver,$globals=$boot.globals;';
 		nextPutAll: 'var $core=$boot.api,nil=$boot.nil,$recv=$boot.asReceiver,$globals=$boot.globals;';
@@ -452,6 +455,24 @@ amdNamespaceOfPackage: aPackage
 	^ (aPackage transport type = 'amd')
 	^ (aPackage transport type = 'amd')
 		ifTrue: [ aPackage transport namespace ]
 		ifTrue: [ aPackage transport namespace ]
 		ifFalse: [ nil ]
 		ifFalse: [ nil ]
+!
+
+importsForOutput: aPackage
+	"Returns an association where key is list of import variables
+	and value is list of external dependencies, with ones imported as variables
+	put at the beginning with same order as is in key.
+	
+	For example imports:{'jQuery'->'jquery'. 'bootstrap'} would yield
+	#('jQuery') -> #('jquery' 'bootstrap')"
+	| namedImports anonImports importVarNames |
+	namedImports := #().
+	anonImports := #().
+	importVarNames := #().
+	aPackage imports do: [ :each | each isString
+		ifTrue: [ anonImports add: each ]
+		ifFalse: [ namedImports add: each value.
+			importVarNames add: each key ]].
+	^ importVarNames -> (namedImports, anonImports)
 ! !
 ! !
 
 
 Object subclass: #ChunkParser
 Object subclass: #ChunkParser