UNPKG

2.69 kBJavaScriptView Raw
1"use strict";
2
3const dynRequire = module.require ? module.require.bind(module) : __non_webpack_require__;
4const getOption = require("./options.js").get;
5
6const AV = require("./assignment-visitor.js");
7const FastPath = require("./fast-path.js");
8const IEV = require("./import-export-visitor.js");
9
10const assignmentVisitor = new AV;
11const importExportVisitor = new IEV;
12
13const codeOfPound = "#".charCodeAt(0);
14const shebangRegExp = /^#!.*/;
15
16const utils = require("./utils.js");
17
18exports.compile = function (code, options) {
19 options = Object.assign(Object.create(null), options);
20
21 if (code.charCodeAt(0) === codeOfPound) {
22 code = code.replace(shebangRegExp, "");
23 }
24
25 const result = {
26 code,
27 ast: null,
28 identical: false
29 };
30
31 // Quickly scan the code to find all possible indexes of import or
32 // export keywords, tolerating some false positives.
33 options.possibleIndexes =
34 utils.findLikelyIndexes(code, ["import", "export"]);
35 const mayHaveImportsOrExports = options.possibleIndexes.length > 0;
36
37 const parse = getOption(options, "parse");
38 if (getOption(options, "ast")) {
39 result.ast = parse(code);
40 }
41
42 options.moduleAlias = getOption(options, "moduleAlias");
43
44 if (
45 ! mayHaveImportsOrExports &&
46 options.moduleAlias === "module" &&
47 getOption(options, "sourceType") !== "module"
48 ) {
49 // Let the caller know the result is no different from the input.
50 result.identical = true;
51 return result;
52 }
53
54 const rootPath = new FastPath(result.ast || parse(code));
55
56 importExportVisitor.visit(rootPath, code, options);
57
58 const magicString = importExportVisitor.magicString;
59 result.identical = ! importExportVisitor.madeChanges;
60
61 if (! result.identical) {
62 assignmentVisitor.visit(rootPath, {
63 exportedLocalNames: importExportVisitor.exportedLocalNames,
64 magicString: magicString,
65 modifyAST: importExportVisitor.modifyAST,
66 moduleAlias: importExportVisitor.moduleAlias
67 });
68 }
69
70 // Whether or not there were any changes, finalizeHoisting does some
71 // important cleanup work, and should not be computationally expensive
72 // when no changes need to be made.
73 importExportVisitor.finalizeHoisting();
74
75 result.code = magicString.toString();
76
77 return result;
78};
79
80exports.transform = function (ast, options) {
81 return dynRequire("./transform.js")(ast, options);
82};
83
84function makeUniqueId(prefix, source) {
85 const scanRegExp = new RegExp("\\b" + prefix + "(\\d*)\\b", "g");
86 let match, max = -1;
87
88 while ((match = scanRegExp.exec(source))) {
89 max = Math.max(max, +(match[1] || 0));
90 }
91
92 if (max >= 0) {
93 return prefix + (max + 1);
94 }
95
96 return prefix;
97}
98
99exports.makeUniqueId = makeUniqueId;