15
15
*/
16
16
package com .google .javascript .jscomp ;
17
17
18
+ import static com .google .javascript .jscomp .parsing .parser .FeatureSet .Feature .MODULES ;
19
+
18
20
import com .google .common .base .Preconditions ;
19
21
import com .google .common .base .Splitter ;
20
22
import com .google .common .collect .ImmutableSet ;
34
36
import java .util .Set ;
35
37
36
38
/**
37
- * Rewrites a ES6 module into a form that can be safely concatenated.
38
- * Note that we treat a file as an ES6 module if it has at least one import or
39
- * export statement.
39
+ * Rewrites a ES6 module into a form that can be safely concatenated. Note that we treat a file as
40
+ * an ES6 module if it has at least one import or export statement.
40
41
*
41
42
* @author moz@google.com (Michael Zhou)
42
43
*/
43
- public final class Es6RewriteModules extends AbstractPostOrderCallback {
44
+ public final class Es6RewriteModules extends AbstractPostOrderCallback
45
+ implements HotSwapCompilerPass {
44
46
private static final String DEFAULT_EXPORT_NAME = "$jscompDefaultExport" ;
45
47
46
48
static final DiagnosticType LHS_OF_GOOG_REQUIRE_MUST_BE_CONST =
@@ -54,13 +56,13 @@ public final class Es6RewriteModules extends AbstractPostOrderCallback {
54
56
"Namespace imports ('goog:some.Namespace') cannot use import * as. "
55
57
+ "Did you mean to import {0} from ''{1}'';?" );
56
58
57
- private final Compiler compiler ;
58
- private int scriptNodeCount = 0 ;
59
+ private final AbstractCompiler compiler ;
60
+ private int scriptNodeCount ;
59
61
60
62
/**
61
63
* Maps exported names to their names in current module.
62
64
*/
63
- private Map <String , NameNodePair > exportMap = new LinkedHashMap <>() ;
65
+ private Map <String , NameNodePair > exportMap ;
64
66
65
67
/**
66
68
* Maps symbol names to a pair of (moduleName, originalName). The original
@@ -69,12 +71,12 @@ public final class Es6RewriteModules extends AbstractPostOrderCallback {
69
71
* object. Eg: "import {foo as f} from 'm'" maps 'f' to the pair ('m', 'foo').
70
72
* In the entry for "import * as ns", the originalName will be the empty string.
71
73
*/
72
- private Map <String , ModuleOriginalNamePair > importMap = new HashMap <>() ;
74
+ private Map <String , ModuleOriginalNamePair > importMap ;
73
75
74
- private Set <String > classes = new HashSet <>() ;
75
- private Set <String > typedefs = new HashSet <>() ;
76
+ private Set <String > classes ;
77
+ private Set <String > typedefs ;
76
78
77
- private Set <String > alreadyRequired = new HashSet <>() ;
79
+ private Set <String > alreadyRequired ;
78
80
79
81
private boolean forceRewrite ;
80
82
@@ -84,7 +86,7 @@ public final class Es6RewriteModules extends AbstractPostOrderCallback {
84
86
* Creates a new Es6RewriteModules instance which can be used to rewrite
85
87
* ES6 modules to a concatenable form.
86
88
*/
87
- public Es6RewriteModules (Compiler compiler ) {
89
+ public Es6RewriteModules (AbstractCompiler compiler ) {
88
90
this .compiler = compiler ;
89
91
}
90
92
@@ -104,6 +106,8 @@ public static boolean isEs6ModuleRoot(Node scriptNode) {
104
106
* "import" or "export" statements. Fails if the file contains a goog.provide or goog.module.
105
107
*
106
108
* @return True, if the file is now an ES6 module. False, if the file must remain a script.
109
+ * TODO(blickly): Move this logic out of this pass, since it is independent of whether or
110
+ * not we are actually transpiling modules
107
111
*/
108
112
public boolean forceToEs6Module (Node root ) {
109
113
if (isEs6ModuleRoot (root )) {
@@ -120,15 +124,42 @@ public boolean forceToEs6Module(Node root) {
120
124
return true ;
121
125
}
122
126
127
+ @ Override
128
+ public void process (Node externs , Node root ) {
129
+ Preconditions .checkState (compiler .getOptions ().getLanguageIn ().toFeatureSet ().has (MODULES ));
130
+ for (Node file = root .getFirstChild (); file != null ; file = file .getNext ()) {
131
+ hotSwapScript (file , null );
132
+ }
133
+ compiler .setFeatureSet (compiler .getFeatureSet ().without (MODULES ));
134
+ }
135
+
136
+ @ Override
137
+ public void hotSwapScript (Node scriptNode , Node originalRoot ) {
138
+ if (isEs6ModuleRoot (scriptNode )) {
139
+ processFile (scriptNode );
140
+ }
141
+ }
142
+
123
143
/**
124
144
* Rewrite a single ES6 module file to a global script version.
125
145
*/
126
- public void processFile (Node root ) {
146
+ private void processFile (Node root ) {
127
147
Preconditions .checkArgument (isEs6ModuleRoot (root ), root );
128
- this . forceRewrite = true ;
148
+ clearState () ;
129
149
NodeTraversal .traverseEs6 (compiler , root , this );
130
150
}
131
151
152
+ public void clearState () {
153
+ this .scriptNodeCount = 0 ;
154
+ this .exportMap = new LinkedHashMap <>();
155
+ this .importMap = new HashMap <>();
156
+ this .classes = new HashSet <>();
157
+ this .typedefs = new HashSet <>();
158
+ this .alreadyRequired = new HashSet <>();
159
+ this .forceRewrite = true ;
160
+ this .googRequireInsertSpot = null ;
161
+ }
162
+
132
163
/**
133
164
* Avoid processing if we find the appearance of goog.provide or goog.module.
134
165
*
@@ -284,8 +315,7 @@ private void visitExport(NodeTraversal t, Node export, Node parent) {
284
315
}
285
316
286
317
if (name != null ) {
287
- Node decl = child .cloneTree ();
288
- decl .setJSDocInfo (child .getJSDocInfo ());
318
+ Node decl = child .detach ();
289
319
parent .replaceChild (export , decl );
290
320
exportMap .put ("default" , new NameNodePair (name , child ));
291
321
} else {
@@ -556,6 +586,7 @@ public void visit(NodeTraversal t, Node n, Node parent) {
556
586
n .setString (newName );
557
587
n .setOriginalName (name );
558
588
}
589
+ t .reportCodeChange (n );
559
590
} else if (var == null && importMap .containsKey (name )) {
560
591
// Change to property access on the imported module object.
561
592
if (parent .isCall () && parent .getFirstChild () == n ) {
@@ -571,6 +602,7 @@ public void visit(NodeTraversal t, Node n, Node parent) {
571
602
IR .getprop (moduleAccess , IR .string (pair .originalName ))
572
603
.useSourceInfoIfMissingFromForTree (n ));
573
604
}
605
+ t .reportCodeChange (moduleAccess );
574
606
}
575
607
}
576
608
}
0 commit comments