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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/scripts/fix_comments.js
diff --git a/third_party/WebKit/Source/devtools/scripts/fix_comments.js b/third_party/WebKit/Source/devtools/scripts/fix_comments.js
new file mode 100644
index 0000000000000000000000000000000000000000..e79a04134089aa4228cd1bac93bd4b670bcc26a2
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/scripts/fix_comments.js
@@ -0,0 +1,316 @@
+const fs = require('fs');
+var escodegen = require('escodegen');
+var esprima = require('esprima');
+
+String.prototype.rtrim = function() {
+ return this.replace(/\s+$/,"");
+}
+
+String.prototype.replaceLineWithin = function(from, to, a, b) {
+ --from;
+ ++to;
+ var chunk = this.substring(from, to);
+ var newChunk = [];
+ for (var line of chunk.split("\n")) {
+ if (line.trim() === a)
+ newChunk.push(line.replace(a, b));
+ else
+ newChunk.push(line);
+ }
+ return this.substring(0, from) + newChunk.join("\n") + this.substring(to);
+}
+
+String.prototype.replaceRange = function(range, replacement) {
+ return this.substring(0, range[0]) + replacement + this.substring(range[1]);
+}
+
+class FileProcessor {
+
+ constructor(filePath)
+ {
+ this._filePath = filePath;
+ this._classInfos = new Map();
+ this._content = fs.readFileSync(filePath).toString();
+
+ var program;
+ try {
+ program = esprima.parse(this._content, {attachComment:true, range: true, loc: true});
+ } catch(e) {
+ console.log("FAILED TO PARSE: " + filePath);
+ return;
+ }
+
+ this._definitions = new Map();
+
+ this._walkAddParent(program, node => this._visit(node));
+ var newContent = this._content;
+
+ for (var name of this._classInfos.keys()) {
+ var newDefinition = [];
+ var commentNode = this._classInfos.get(name).constructorCommentNode;
+ var constructorNode = this._classInfos.get(name).constructorNode;
+ var prototypeNode = this._classInfos.get(name).prototypeNode;
+ var comment = commentNode ? this._text(commentNode) : "";
+ if (!comment || !comment.includes("@constructor"))
+ continue;
+ var moduleName = filePath.replace(/front_end\/([^/]+)\/.*/, "$1");
+ if (moduleName.endsWith("_lazy"))
+ moduleName = moduleName.substring(0, moduleName.length - "_lazy".length);
+
+ if (moduleName === "accessibility")
+ moduleName = "a11y";
+ if (moduleName === "resources")
+ moduleName = "storage";
+ if (moduleName === "heap_snapshot_worker")
+ moduleName = "heap_worker";
+ if (moduleName === "timeline")
+ moduleName = "timeline_ui";
+ if (moduleName === "timeline_module")
+ moduleName = "timeline";
+
+ var newName = name.replace("WebInspector.", moduleName + ".");
+ var capModule = moduleName.substring(0, 1).toUpperCase() + moduleName.substring(1);
+ var prefix = moduleName + "." + capModule;
+ if (newName.startsWith(prefix) && newName.length > prefix.length)
+ newName = newName.replace(prefix, moduleName + ".");
+
+ console.log(newName);
+
+ var commentLines = comment.split("\n");
+ var implementsLines = [];
+ for (var commentLine of commentLines) {
+ var implementsMatch = commentLine.match(/@implements {(.*)}/);
+ if (implementsMatch)
+ implementsLines.push(` * @implements {${implementsMatch[1]}} `);
+ var templateMatch = commentLine.match(/@template/);
+ if (templateMatch)
+ implementsLines.push(commentLine);
+ }
+ implementsLines.push(" * @unrestricted");
+ newDefinition.push(`/**\n${implementsLines.join("\n")}\n*/\n`);
+
+ if (constructorNode.type === "FunctionDeclaration")
+ newDefinition.push(`var ${name} = class `);
+ else
+ newDefinition.push(`${name} = class `);
+
+ var extendsMatch = comment.match(/@extends {(.*)}/);
+ let superName;
+ if (extendsMatch)
+ superName = extendsMatch[1];
+
+ if (superName)
+ newDefinition.push(`extends ${superName} {`);
+ else
+ newDefinition.push(`{`);
+
+ if (comment) {
+ comment = comment.replace(/^/gm, " ").substring(2);
+ comment = comment.replace(/\s*@implements.*/g, "");
+ comment = comment.replace(/\s*@extends.*/, "");
+ comment = comment.replace(/\s*@constructor/, "");
+ comment = comment.replace(/\s*@template.*/g, "");
+ comment = comment.split("\n").filter(line => line.trim() !== "*").join("\n");
+ if (comment.replace(/[*/]/g, "").trim())
+ newDefinition.push(`\n ${comment}`);
+ }
+
+ var constructorText = this._text(constructorNode).trim();
+ constructorText = constructorText.replace(/^/gm, " ");
+ var lines = constructorText.split("\n");
+ lines[0] = lines[0].replace(`function ${name}`, " constructor");
+ lines[0] = lines[0].replace(`function(`, " constructor(");
+ constructorText = lines.join("\n");
+ if (constructorText.includes(`${superName}.call`)) {
+ constructorText = constructorText.replace(`${superName}.call(this, `, "super(");
+ constructorText = constructorText.replace(`${superName}.call(this)`, "super()");
+ } else if (superName) {
+ constructorText = constructorText.replace("{", "{\n super();");
+ }
+
+ if (constructorText.replace(/constructor[^{]+{/m, "").replace(/.*}/, "").trim()) {
+ newDefinition.push("\n");
+ newDefinition.push(constructorText);
+ }
+
+ if (prototypeNode) {
+ // Remove block comma
+ var prototypeText = this._text(prototypeNode);
+ for (var i = 0; i < prototypeNode.properties.length; ++i) {
+ var previous = prototypeNode.properties[i - 1];
+ var property = prototypeNode.properties[i];
+ prototypeText = prototypeText.replaceLineWithin(previous ? previous.range[1] - prototypeNode.range[0] : 0, property.range[0] - prototypeNode.range[0], "},", "} ");
+ }
+ prototypeText = prototypeText.replaceLineWithin(property ? property.range[1] - prototypeNode.range[0] : prototypeNode.range[1] - prototypeNode.range[0], prototypeNode.range[1] - prototypeNode.range[0], "},", "} ");
+
+ prototypeText = prototypeText.replace(/(^\s+[\w]+)\:\s?function/mg, "$1");
+ prototypeText = prototypeText.replace(new RegExp(`${superName}\.prototype\.([^.]+)\.call\\(this, `, 'g'), "super.$1(");
+ prototypeText = prototypeText.replace(new RegExp(`${superName}\.prototype\.([^.]+)\.call\\(this\\)`, 'g'), "super.$1()");
+ prototypeText = prototypeText.replace(new RegExp(`^\\s+__proto__\\s*:\\s*${superName}.*`, "m"), "");
+
+ newDefinition.push("\n");
+ newDefinition.push(prototypeText.substring(1, prototypeText.length - 2));
+ }
+ newDefinition.push("\n}\n");
+ this._definitions.set(name, newDefinition.join(""));;
+ }
+
+ var newContent = this._content;
+ for (var name of this._definitions.keys()) {
+ var classInfo = this._classInfos.get(name);
+
+ newContent = this._replaceRange(newContent, classInfo.constructorCommentNode.range, "");
+ newContent = this._replaceRange(newContent, classInfo.constructorNode.range, this._definitions.get(name));
+
+
+ if (classInfo.prototypeNode)
+ newContent = this._replaceRange(newContent, classInfo.prototypeNode.range, "");
+ }
+
+ for (var name of this._definitions.keys()) {
+ newContent = newContent.replace(`${name} = ${name} =`, `${name} =`);
+ newContent = newContent.replace(`${name} = /**`, `/**`);
+ newContent = newContent.replace(`${name}.prototype = ;`, "");
+ newContent = newContent.replace(`${name}.prototype =\n;`, "");
+ }
+ newContent = newContent.trim();
+ newContent = newContent.replace(/\n\n\n/g, "\n\n");
+ newContent = newContent.replace(/}\n;/g, "};");
+ newContent = newContent.split("\n").map(line => line.rtrim()).join("\n");
+ newContent = newContent.replace("\n\n", "\n") + "\n";
+ fs.writeFileSync(filePath, newContent);
+ }
+
+ _replaceRange(text, range, newContent)
+ {
+ range = range.slice();
+ var result = text.substring(0, range[0]) + newContent + text.substring(range[1]);
+ var newLength = newContent.length;
+ for (var name of this._definitions.keys()) {
+ var classInfo = this._classInfos.get(name);
+ this._patchRange(classInfo.constructorCommentNode.range, range, newLength);
+ this._patchRange(classInfo.constructorNode.range, range, newLength);
+ if (classInfo.prototypeNode)
+ this._patchRange(classInfo.prototypeNode.range, range, newLength);
+ }
+ return result;
+ }
+
+ _patchRange(range, shift, newLength)
+ {
+ var oldLength = shift[1] - shift[0];
+ if (shift[0] > range[1])
+ return;
+ if (shift[1] < range[0]) {
+ range[0] += newLength - oldLength;
+ range[1] += newLength - oldLength;
+ return;
+ }
+ if (shift[0] == range[0] && shift[1] == range[1]) {
+ range[1] = range[0];
+ return;
+ }
+ console.error("POOR RANGE", this._filePath, range, shift);
+ }
+
+ _classInfo(name) {
+ var result = this._classInfos.get(name);
+ if (!result) {
+ result = {};
+ this._classInfos.set(name, result);
+ }
+ return result;
+ }
+
+ _log(title, node) {
+ if (node)
+ console.log(title + " : " + node.range[0] + ":" + node.range[1] + " " + this._text(node));
+ }
+
+ _text(node) {
+ return this._content.substring(node.range[0], node.range[1]);
+ }
+
+ _visit(node) {
+ var leadingComments = node.leadingComments || (node.parent && node.parent.leadingComments) || (node.parent && node.parent.parent && node.parent.parent.leadingComments);
+ var comment = null;
+ if (leadingComments) {
+ comment = leadingComments[leadingComments.length - 1];
+ var validComment = node.range[0] > comment.range[1] && this._content.substring(comment.range[1], node.range[0]).replace(/[^\n]/g, "").length < 2;
+ if (!validComment)
+ comment = null;
+ }
+
+ if (node.type === "FunctionDeclaration") {
+ var classInfo = this._classInfo(node.id.name);
+ classInfo.constructorCommentNode = comment;
+ classInfo.constructorNode = node;
+ return;
+ }
+
+ if (node.type === "FunctionExpression") {
+ if (!node.parent || !node.parent.left)
+ return;
+ var name = this._text(node.parent.left);
+ var classInfo = this._classInfo(name);
+ classInfo.constructorCommentNode = comment;
+ classInfo.constructorNode = node.parent.right;
+ return;
+ }
+
+ if (node.type === "AssignmentExpression" && node.left.property && node.left.property.name === "prototype") {
+ var protoName = this._text(node.left);
+ var name = protoName.substring(0, protoName.length - ".prototype".length);
+ this._classInfo(name).prototypeNode = node.right;
+ return;
+ }
+ }
+
+ _walkAddParent(ast, fn) {
+ var stack = [ast];
+ for (var i = 0; i < stack.length; i += 1) {
+ var node = stack[i];
+ fn(node);
+ for (var key in node) {
+ if (key !== 'parent') {
+ var child = node[key];
+ if (child instanceof Array) {
+ if (typeof child[0] === "number")
+ continue;
+ var len = child.length;
+ for (var j = 0; j < len; j += 1) {
+ var subchild = child[j];
+ subchild.parent = node;
+ stack.push(subchild);
+ }
+ } else if (child != void 0 && typeof child.type === 'string') {
+ child.parent = node;
+ stack.push(child);
+ }
+ }
+ }
+ }
+ }
+}
+
+function walkSync(currentDirPath) {
+ var fs = require('fs'),
+ path = require('path');
+ fs.readdirSync(currentDirPath).forEach(function (name) {
+ var filePath = path.join(currentDirPath, name);
+ var stat = fs.statSync(filePath);
+ if (stat.isFile() && filePath.endsWith(".js")) {
+ if (filePath.includes("ExtensionAPI.js"))
+ return;
+ if (filePath.includes("externs.js"))
+ return;
+ if (filePath.includes("eslint") || filePath.includes("lighthouse-background.js") || filePath.includes("/cm/") || filePath.includes("/cm_modes/") || filePath.includes("/xterm.js/") || filePath.includes("/acorn/") || filePath.includes("/gonzales/"))
+ return;
+ new FileProcessor(filePath);
+ } else if (stat.isDirectory()) {
+ walkSync(filePath);
+ }
+ });
+}
+
+walkSync('front_end');

Powered by Google App Engine
This is Rietveld 408576698