source: frontend/node_modules/webpack/lib/util/concatenate.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const Template = require("../Template");
9
10/** @typedef {import("estree").Node} Node */
11/** @typedef {import("../javascript/JavascriptModulesPlugin").Scope} Scope */
12/** @typedef {import("../javascript/JavascriptModulesPlugin").Reference} Reference */
13/** @typedef {import("../javascript/JavascriptModulesPlugin").Variable} Variable */
14/** @typedef {import("../javascript/JavascriptParser").Range} Range */
15/** @typedef {Set<string>} UsedNames */
16
17const DEFAULT_EXPORT = "__WEBPACK_DEFAULT_EXPORT__";
18const NAMESPACE_OBJECT_EXPORT = "__WEBPACK_NAMESPACE_OBJECT__";
19
20/**
21 * Gets all references.
22 * @param {Variable} variable variable
23 * @returns {Reference[]} references
24 */
25const getAllReferences = (variable) => {
26 let set = variable.references;
27 // Look for inner scope variables too (like in class Foo { t() { Foo } })
28 const identifiers = new Set(variable.identifiers);
29 for (const scope of variable.scope.childScopes) {
30 for (const innerVar of scope.variables) {
31 if (innerVar.identifiers.some((id) => identifiers.has(id))) {
32 set = [...set, ...innerVar.references];
33 break;
34 }
35 }
36 }
37 return set;
38};
39
40/**
41 * Returns result.
42 * @param {Node | Node[]} ast ast
43 * @param {Node} node node
44 * @returns {undefined | Node[]} result
45 */
46const getPathInAst = (ast, node) => {
47 if (ast === node) {
48 return [];
49 }
50
51 const nr = /** @type {Range} */ (node.range);
52
53 /**
54 * Returns result.
55 * @param {Node} n node
56 * @returns {Node[] | undefined} result
57 */
58 const enterNode = (n) => {
59 if (!n) return;
60 const r = n.range;
61 if (r && r[0] <= nr[0] && r[1] >= nr[1]) {
62 const path = getPathInAst(n, node);
63 if (path) {
64 path.push(n);
65 return path;
66 }
67 }
68 };
69
70 if (Array.isArray(ast)) {
71 for (let i = 0; i < ast.length; i++) {
72 const enterResult = enterNode(ast[i]);
73 if (enterResult !== undefined) return enterResult;
74 }
75 } else if (ast && typeof ast === "object") {
76 const keys =
77 /** @type {(keyof Node)[]} */
78 (Object.keys(ast));
79 for (let i = 0; i < keys.length; i++) {
80 // We are making the faster check in `enterNode` using `n.range`
81 const value =
82 ast[
83 /** @type {Exclude<keyof Node, "range" | "loc" | "leadingComments" | "trailingComments">} */
84 (keys[i])
85 ];
86 if (Array.isArray(value)) {
87 const pathResult = getPathInAst(value, node);
88 if (pathResult !== undefined) return pathResult;
89 } else if (value && typeof value === "object") {
90 const enterResult = enterNode(value);
91 if (enterResult !== undefined) return enterResult;
92 }
93 }
94 }
95};
96
97/**
98 * Returns found new name.
99 * @param {string} oldName old name
100 * @param {UsedNames} usedNamed1 used named 1
101 * @param {UsedNames} usedNamed2 used named 2
102 * @param {string} extraInfo extra info
103 * @returns {string} found new name
104 */
105function findNewName(oldName, usedNamed1, usedNamed2, extraInfo) {
106 let name = oldName;
107
108 if (name === DEFAULT_EXPORT) {
109 name = "";
110 }
111 if (name === NAMESPACE_OBJECT_EXPORT) {
112 name = "namespaceObject";
113 }
114
115 // Remove uncool stuff
116 extraInfo = extraInfo.replace(
117 /\.+\/|(?:\/index)?\.[a-zA-Z0-9]{1,4}(?:$|\s|\?)|\s*\+\s*\d+\s*modules/g,
118 ""
119 );
120
121 const splittedInfo = extraInfo.split("/");
122 while (splittedInfo.length) {
123 name = splittedInfo.pop() + (name ? `_${name}` : "");
124 const nameIdent = Template.toIdentifier(name);
125 if (
126 !usedNamed1.has(nameIdent) &&
127 (!usedNamed2 || !usedNamed2.has(nameIdent))
128 ) {
129 return nameIdent;
130 }
131 }
132
133 let i = 0;
134 let nameWithNumber = Template.toIdentifier(`${name}_${i}`);
135 while (
136 usedNamed1.has(nameWithNumber) ||
137 // eslint-disable-next-line no-unmodified-loop-condition
138 (usedNamed2 && usedNamed2.has(nameWithNumber))
139 ) {
140 i++;
141 nameWithNumber = Template.toIdentifier(`${name}_${i}`);
142 }
143 return nameWithNumber;
144}
145
146/** @typedef {Set<Scope>} ScopeSet */
147
148/**
149 * Adds scope symbols.
150 * @param {Scope | null} s scope
151 * @param {UsedNames} nameSet name set
152 * @param {ScopeSet} scopeSet1 scope set 1
153 * @param {ScopeSet} scopeSet2 scope set 2
154 */
155const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => {
156 let scope = s;
157 while (scope) {
158 if (scopeSet1.has(scope)) break;
159 if (scopeSet2.has(scope)) break;
160 scopeSet1.add(scope);
161 for (const variable of scope.variables) {
162 nameSet.add(variable.name);
163 }
164 scope = scope.upper;
165 }
166};
167
168const RESERVED_NAMES = new Set(
169 [
170 // internal names (should always be renamed)
171 DEFAULT_EXPORT,
172 NAMESPACE_OBJECT_EXPORT,
173
174 // keywords
175 "abstract,arguments,async,await,boolean,break,byte,case,catch,char,class,const,continue",
176 "debugger,default,delete,do,double,else,enum,eval,export,extends,false,final,finally,float",
177 "for,function,goto,if,implements,import,in,instanceof,int,interface,let,long,native,new,null",
178 "package,private,protected,public,return,short,static,super,switch,synchronized,this,throw",
179 "throws,transient,true,try,typeof,var,void,volatile,while,with,yield",
180
181 // commonjs/amd
182 "module,__dirname,__filename,exports,require,define",
183
184 // js globals
185 "Array,Date,eval,function,hasOwnProperty,Infinity,isFinite,isNaN,isPrototypeOf,length,Math",
186 "NaN,name,Number,Object,prototype,String,Symbol,toString,undefined,valueOf",
187
188 // browser globals
189 "alert,all,anchor,anchors,area,assign,blur,button,checkbox,clearInterval,clearTimeout",
190 "clientInformation,close,closed,confirm,constructor,crypto,decodeURI,decodeURIComponent",
191 "defaultStatus,document,element,elements,embed,embeds,encodeURI,encodeURIComponent,escape",
192 "event,fileUpload,focus,form,forms,frame,innerHeight,innerWidth,layer,layers,link,location",
193 "mimeTypes,navigate,navigator,frames,frameRate,hidden,history,image,images,offscreenBuffering",
194 "open,opener,option,outerHeight,outerWidth,packages,pageXOffset,pageYOffset,parent,parseFloat",
195 "parseInt,password,pkcs11,plugin,prompt,propertyIsEnum,radio,reset,screenX,screenY,scroll",
196 "secure,select,self,setInterval,setTimeout,status,submit,taint,text,textarea,top,unescape",
197 "untaint,window",
198
199 // window events
200 "onblur,onclick,onerror,onfocus,onkeydown,onkeypress,onkeyup,onmouseover,onload,onmouseup,onmousedown,onsubmit"
201 ]
202 .join(",")
203 .split(",")
204);
205
206/** @typedef {{ usedNames: UsedNames, alreadyCheckedScopes: ScopeSet }} ScopeInfo */
207/** @typedef {Map<string, ScopeInfo>} UsedNamesInScopeInfo */
208
209/**
210 * Gets used names in scope info.
211 * @param {UsedNamesInScopeInfo} usedNamesInScopeInfo used names in scope info
212 * @param {string} module module identifier
213 * @param {string} id export id
214 * @returns {ScopeInfo} info
215 */
216const getUsedNamesInScopeInfo = (usedNamesInScopeInfo, module, id) => {
217 const key = `${module}-${id}`;
218 let info = usedNamesInScopeInfo.get(key);
219 if (info === undefined) {
220 info = {
221 usedNames: new Set(),
222 alreadyCheckedScopes: new Set()
223 };
224 usedNamesInScopeInfo.set(key, info);
225 }
226 return info;
227};
228
229module.exports = {
230 DEFAULT_EXPORT,
231 NAMESPACE_OBJECT_EXPORT,
232 RESERVED_NAMES,
233 addScopeSymbols,
234 findNewName,
235 getAllReferences,
236 getPathInAst,
237 getUsedNamesInScopeInfo
238};
Note: See TracBrowser for help on using the repository browser.