Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: third_party/WebKit/Source/devtools/scripts/fix_comments.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 const fs = require('fs');
2 var escodegen = require('escodegen');
3 var esprima = require('esprima');
4
5 String.prototype.rtrim = function() {
6 return this.replace(/\s+$/,"");
7 }
8
9 String.prototype.replaceLineWithin = function(from, to, a, b) {
10 --from;
11 ++to;
12 var chunk = this.substring(from, to);
13 var newChunk = [];
14 for (var line of chunk.split("\n")) {
15 if (line.trim() === a)
16 newChunk.push(line.replace(a, b));
17 else
18 newChunk.push(line);
19 }
20 return this.substring(0, from) + newChunk.join("\n") + this.substring(to);
21 }
22
23 String.prototype.replaceRange = function(range, replacement) {
24 return this.substring(0, range[0]) + replacement + this.substring(range[1]);
25 }
26
27 class FileProcessor {
28
29 constructor(filePath)
30 {
31 this._filePath = filePath;
32 this._classInfos = new Map();
33 this._content = fs.readFileSync(filePath).toString();
34
35 var program;
36 try {
37 program = esprima.parse(this._content, {attachComment:true, range: t rue, loc: true});
38 } catch(e) {
39 console.log("FAILED TO PARSE: " + filePath);
40 return;
41 }
42
43 this._definitions = new Map();
44
45 this._walkAddParent(program, node => this._visit(node));
46 var newContent = this._content;
47
48 for (var name of this._classInfos.keys()) {
49 var newDefinition = [];
50 var commentNode = this._classInfos.get(name).constructorCommentNode;
51 var constructorNode = this._classInfos.get(name).constructorNode;
52 var prototypeNode = this._classInfos.get(name).prototypeNode;
53 var comment = commentNode ? this._text(commentNode) : "";
54 if (!comment || !comment.includes("@constructor"))
55 continue;
56 var moduleName = filePath.replace(/front_end\/([^/]+)\/.*/, "$1");
57 if (moduleName.endsWith("_lazy"))
58 moduleName = moduleName.substring(0, moduleName.length - "_lazy" .length);
59
60 if (moduleName === "accessibility")
61 moduleName = "a11y";
62 if (moduleName === "resources")
63 moduleName = "storage";
64 if (moduleName === "heap_snapshot_worker")
65 moduleName = "heap_worker";
66 if (moduleName === "timeline")
67 moduleName = "timeline_ui";
68 if (moduleName === "timeline_module")
69 moduleName = "timeline";
70
71 var newName = name.replace("WebInspector.", moduleName + ".");
72 var capModule = moduleName.substring(0, 1).toUpperCase() + moduleNam e.substring(1);
73 var prefix = moduleName + "." + capModule;
74 if (newName.startsWith(prefix) && newName.length > prefix.length)
75 newName = newName.replace(prefix, moduleName + ".");
76
77 console.log(newName);
78
79 var commentLines = comment.split("\n");
80 var implementsLines = [];
81 for (var commentLine of commentLines) {
82 var implementsMatch = commentLine.match(/@implements {(.*)}/);
83 if (implementsMatch)
84 implementsLines.push(` * @implements {${implementsMatch[1]}} `);
85 var templateMatch = commentLine.match(/@template/);
86 if (templateMatch)
87 implementsLines.push(commentLine);
88 }
89 implementsLines.push(" * @unrestricted");
90 newDefinition.push(`/**\n${implementsLines.join("\n")}\n*/\n`);
91
92 if (constructorNode.type === "FunctionDeclaration")
93 newDefinition.push(`var ${name} = class `);
94 else
95 newDefinition.push(`${name} = class `);
96
97 var extendsMatch = comment.match(/@extends {(.*)}/);
98 let superName;
99 if (extendsMatch)
100 superName = extendsMatch[1];
101
102 if (superName)
103 newDefinition.push(`extends ${superName} {`);
104 else
105 newDefinition.push(`{`);
106
107 if (comment) {
108 comment = comment.replace(/^/gm, " ").substring(2);
109 comment = comment.replace(/\s*@implements.*/g, "");
110 comment = comment.replace(/\s*@extends.*/, "");
111 comment = comment.replace(/\s*@constructor/, "");
112 comment = comment.replace(/\s*@template.*/g, "");
113 comment = comment.split("\n").filter(line => line.trim() !== "*" ).join("\n");
114 if (comment.replace(/[*/]/g, "").trim())
115 newDefinition.push(`\n ${comment}`);
116 }
117
118 var constructorText = this._text(constructorNode).trim();
119 constructorText = constructorText.replace(/^/gm, " ");
120 var lines = constructorText.split("\n");
121 lines[0] = lines[0].replace(`function ${name}`, " constructor");
122 lines[0] = lines[0].replace(`function(`, " constructor(");
123 constructorText = lines.join("\n");
124 if (constructorText.includes(`${superName}.call`)) {
125 constructorText = constructorText.replace(`${superName}.call(thi s, `, "super(");
126 constructorText = constructorText.replace(`${superName}.call(thi s)`, "super()");
127 } else if (superName) {
128 constructorText = constructorText.replace("{", "{\n super ();");
129 }
130
131 if (constructorText.replace(/constructor[^{]+{/m, "").replace(/.*}/, "").trim()) {
132 newDefinition.push("\n");
133 newDefinition.push(constructorText);
134 }
135
136 if (prototypeNode) {
137 // Remove block comma
138 var prototypeText = this._text(prototypeNode);
139 for (var i = 0; i < prototypeNode.properties.length; ++i) {
140 var previous = prototypeNode.properties[i - 1];
141 var property = prototypeNode.properties[i];
142 prototypeText = prototypeText.replaceLineWithin(previous ? p revious.range[1] - prototypeNode.range[0] : 0, property.range[0] - prototypeNode .range[0], "},", "} ");
143 }
144 prototypeText = prototypeText.replaceLineWithin(property ? prope rty.range[1] - prototypeNode.range[0] : prototypeNode.range[1] - prototypeNode.r ange[0], prototypeNode.range[1] - prototypeNode.range[0], "},", "} ");
145
146 prototypeText = prototypeText.replace(/(^\s+[\w]+)\:\s?function/ mg, "$1");
147 prototypeText = prototypeText.replace(new RegExp(`${superName}\. prototype\.([^.]+)\.call\\(this, `, 'g'), "super.$1(");
148 prototypeText = prototypeText.replace(new RegExp(`${superName}\. prototype\.([^.]+)\.call\\(this\\)`, 'g'), "super.$1()");
149 prototypeText = prototypeText.replace(new RegExp(`^\\s+__proto__ \\s*:\\s*${superName}.*`, "m"), "");
150
151 newDefinition.push("\n");
152 newDefinition.push(prototypeText.substring(1, prototypeText.leng th - 2));
153 }
154 newDefinition.push("\n}\n");
155 this._definitions.set(name, newDefinition.join(""));;
156 }
157
158 var newContent = this._content;
159 for (var name of this._definitions.keys()) {
160 var classInfo = this._classInfos.get(name);
161
162 newContent = this._replaceRange(newContent, classInfo.constructorCom mentNode.range, "");
163 newContent = this._replaceRange(newContent, classInfo.constructorNod e.range, this._definitions.get(name));
164
165
166 if (classInfo.prototypeNode)
167 newContent = this._replaceRange(newContent, classInfo.prototypeN ode.range, "");
168 }
169
170 for (var name of this._definitions.keys()) {
171 newContent = newContent.replace(`${name} = ${name} =`, `${name} =`);
172 newContent = newContent.replace(`${name} = /**`, `/**`);
173 newContent = newContent.replace(`${name}.prototype = ;`, "");
174 newContent = newContent.replace(`${name}.prototype =\n;`, "");
175 }
176 newContent = newContent.trim();
177 newContent = newContent.replace(/\n\n\n/g, "\n\n");
178 newContent = newContent.replace(/}\n;/g, "};");
179 newContent = newContent.split("\n").map(line => line.rtrim()).join("\n") ;
180 newContent = newContent.replace("\n\n", "\n") + "\n";
181 fs.writeFileSync(filePath, newContent);
182 }
183
184 _replaceRange(text, range, newContent)
185 {
186 range = range.slice();
187 var result = text.substring(0, range[0]) + newContent + text.substring(r ange[1]);
188 var newLength = newContent.length;
189 for (var name of this._definitions.keys()) {
190 var classInfo = this._classInfos.get(name);
191 this._patchRange(classInfo.constructorCommentNode.range, range, newL ength);
192 this._patchRange(classInfo.constructorNode.range, range, newLength);
193 if (classInfo.prototypeNode)
194 this._patchRange(classInfo.prototypeNode.range, range, newLength );
195 }
196 return result;
197 }
198
199 _patchRange(range, shift, newLength)
200 {
201 var oldLength = shift[1] - shift[0];
202 if (shift[0] > range[1])
203 return;
204 if (shift[1] < range[0]) {
205 range[0] += newLength - oldLength;
206 range[1] += newLength - oldLength;
207 return;
208 }
209 if (shift[0] == range[0] && shift[1] == range[1]) {
210 range[1] = range[0];
211 return;
212 }
213 console.error("POOR RANGE", this._filePath, range, shift);
214 }
215
216 _classInfo(name) {
217 var result = this._classInfos.get(name);
218 if (!result) {
219 result = {};
220 this._classInfos.set(name, result);
221 }
222 return result;
223 }
224
225 _log(title, node) {
226 if (node)
227 console.log(title + " : " + node.range[0] + ":" + node.range[1] + " " + this._text(node));
228 }
229
230 _text(node) {
231 return this._content.substring(node.range[0], node.range[1]);
232 }
233
234 _visit(node) {
235 var leadingComments = node.leadingComments || (node.parent && node.paren t.leadingComments) || (node.parent && node.parent.parent && node.parent.parent.l eadingComments);
236 var comment = null;
237 if (leadingComments) {
238 comment = leadingComments[leadingComments.length - 1];
239 var validComment = node.range[0] > comment.range[1] && this._content .substring(comment.range[1], node.range[0]).replace(/[^\n]/g, "").length < 2;
240 if (!validComment)
241 comment = null;
242 }
243
244 if (node.type === "FunctionDeclaration") {
245 var classInfo = this._classInfo(node.id.name);
246 classInfo.constructorCommentNode = comment;
247 classInfo.constructorNode = node;
248 return;
249 }
250
251 if (node.type === "FunctionExpression") {
252 if (!node.parent || !node.parent.left)
253 return;
254 var name = this._text(node.parent.left);
255 var classInfo = this._classInfo(name);
256 classInfo.constructorCommentNode = comment;
257 classInfo.constructorNode = node.parent.right;
258 return;
259 }
260
261 if (node.type === "AssignmentExpression" && node.left.property && node.l eft.property.name === "prototype") {
262 var protoName = this._text(node.left);
263 var name = protoName.substring(0, protoName.length - ".prototype".le ngth);
264 this._classInfo(name).prototypeNode = node.right;
265 return;
266 }
267 }
268
269 _walkAddParent(ast, fn) {
270 var stack = [ast];
271 for (var i = 0; i < stack.length; i += 1) {
272 var node = stack[i];
273 fn(node);
274 for (var key in node) {
275 if (key !== 'parent') {
276 var child = node[key];
277 if (child instanceof Array) {
278 if (typeof child[0] === "number")
279 continue;
280 var len = child.length;
281 for (var j = 0; j < len; j += 1) {
282 var subchild = child[j];
283 subchild.parent = node;
284 stack.push(subchild);
285 }
286 } else if (child != void 0 && typeof child.type === 'string' ) {
287 child.parent = node;
288 stack.push(child);
289 }
290 }
291 }
292 }
293 }
294 }
295
296 function walkSync(currentDirPath) {
297 var fs = require('fs'),
298 path = require('path');
299 fs.readdirSync(currentDirPath).forEach(function (name) {
300 var filePath = path.join(currentDirPath, name);
301 var stat = fs.statSync(filePath);
302 if (stat.isFile() && filePath.endsWith(".js")) {
303 if (filePath.includes("ExtensionAPI.js"))
304 return;
305 if (filePath.includes("externs.js"))
306 return;
307 if (filePath.includes("eslint") || filePath.includes("lighthouse-bac kground.js") || filePath.includes("/cm/") || filePath.includes("/cm_modes/") || filePath.includes("/xterm.js/") || filePath.includes("/acorn/") || filePath.incl udes("/gonzales/"))
308 return;
309 new FileProcessor(filePath);
310 } else if (stat.isDirectory()) {
311 walkSync(filePath);
312 }
313 });
314 }
315
316 walkSync('front_end');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698