UNPKG

3.04 kBJavaScriptView Raw
1"use strict";
2
3const assert = require("assert");
4let namespace;
5let ibsPropertyName = "isBlockScoped";
6let types;
7let cache;
8
9function tryScopedLibDirect() {
10 namespace = require("@babel/types/lib/validators/isBlockScoped");
11
12 // If the above import succeeded, then we should replace the .default
13 // property of the isBlockScoped module, instead of .isBlockScoped.
14 ibsPropertyName = "default";
15
16 types = types || require("@babel/types");
17 cache = cache || require("@babel/traverse").default.cache;
18}
19
20function tryScoped() {
21 namespace = require("@babel/types");
22 types = types || require("@babel/types");
23 cache = cache || require("@babel/traverse").default.cache;
24}
25
26function tryScopedLib() {
27 namespace = require("@babel/types/lib/validators");
28 types = types || require("@babel/types");
29 cache = cache || require("@babel/traverse").default.cache;
30}
31
32function tryUnscoped() {
33 namespace = require("babel-types/lib/validators");
34 types = types || require("babel-types");
35 cache = cache || require("babel-traverse").default.cache;
36}
37
38[tryScopedLibDirect,
39 tryScoped,
40 tryScopedLib,
41 tryUnscoped
42].some(function (fn) {
43 try {
44 fn();
45 } catch (e) {
46 return false;
47 }
48
49 const wrapped = namespace[ibsPropertyName];
50 assert.strictEqual(typeof wrapped, "function")
51
52 // Allow types.isBlockScoped to return true for import-related nodes.
53 const wrapper = namespace[ibsPropertyName] = function (node) {
54 return node &&
55 types.isImportDeclaration(node) ||
56 wrapped.apply(this, arguments);
57 };
58
59 // The wrapping can fail if namespace[ibsPropertyName] is a non-writable
60 // property (such as a getter function).
61 if (namespace[ibsPropertyName] !== wrapper) {
62 throw new Error(
63 "Unable to patch @babel/types isBlockScoped function"
64 );
65 }
66
67 return true;
68});
69
70module.exports = function (context) {
71 const compiler = require("../lib/compiler.js");
72 const transformOptions = {
73 parse: require("../lib/parsers/babel.js").parse
74 };
75
76 let madeChanges = false;
77 function transform(node) {
78 const result = compiler.transform(node, transformOptions);
79 if (! result.identical) {
80 madeChanges = true;
81 // If the Reify compiler made any changes, invalidate all existing
82 // Scope objects, so that any variable binding changes made by
83 // compiler.transform will be reflected accurately.
84 cache.clearScope();
85 }
86 return result;
87 }
88
89 return {
90 visitor: {
91 Program: {
92 enter(path) {
93 const code = path.hub.file.code;
94 if (typeof code === "string") {
95 transformOptions.moduleAlias =
96 compiler.makeUniqueId("module", code);
97 }
98 transformOptions.finalCompilationPass = false;
99 Object.assign(transformOptions, this.opts);
100 transform(path.node);
101 },
102
103 exit(path) {
104 transformOptions.finalCompilationPass = true;
105 const ast = transform(path.node).ast;
106 assert.strictEqual(ast.type, "Program");
107 }
108 }
109 }
110 };
111};