mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-09-29 05:34:21 +08:00
R=jacktfranklin@chromium.org Bug: 1222126 Change-Id: I27247553cfcb85e9980b217d7d55fb8c9bcf1238 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3341595 Commit-Queue: Tim Van der Lippe <tvanderlippe@chromium.org> Auto-Submit: Tim Van der Lippe <tvanderlippe@chromium.org> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Commit-Queue: Jack Franklin <jacktfranklin@chromium.org>
67 lines
2.3 KiB
JavaScript
67 lines
2.3 KiB
JavaScript
// Copyright 2021 The Chromium Authors. All rights reserved.
|
||
// Use of this source code is governed by a BSD-style license that can be
|
||
// found in the LICENSE file.
|
||
|
||
const {Project, ts, SyntaxKind, StructureKind} = require('ts-morph');
|
||
const path = require('path');
|
||
const project = new Project({
|
||
tsConfigFilePath: '../devtools-frontend/tsconfig.json',
|
||
});
|
||
|
||
function isWithinContructor(classNode, reference) {
|
||
const constructors = classNode.getConstructors();
|
||
if (!constructors.length) {
|
||
return false;
|
||
}
|
||
|
||
if (constructors.length !== 1) {
|
||
throw new Error('More than one constructor');
|
||
}
|
||
return reference.getAncestors().includes(constructors[0]);
|
||
}
|
||
|
||
const files = project.getSourceFiles();
|
||
for (const file of files) {
|
||
const filePath = file.getFilePath();
|
||
if (!filePath.startsWith(
|
||
path.normalize(path.join(process.cwd(), '..', 'devtools-frontend', 'front_end', process.argv[2])))) {
|
||
continue;
|
||
}
|
||
console.log(filePath);
|
||
if (filePath.includes('third_party') || filePath.includes('generated') || filePath.endsWith('.d.ts')) {
|
||
continue;
|
||
}
|
||
const classNodes = file.getClasses();
|
||
for (const classNode of classNodes) {
|
||
for (const property of classNode.getInstanceMembers()) {
|
||
const name = property.getStructure().name;
|
||
console.log(name);
|
||
if (name.startsWith('#') || !property.hasModifier(SyntaxKind.PrivateKeyword)) {
|
||
continue;
|
||
}
|
||
|
||
if (isWithinContructor(classNode, property)) {
|
||
continue;
|
||
}
|
||
|
||
const newName = `#${name}`;
|
||
|
||
property.toggleModifier('private', false);
|
||
property.rename(newName);
|
||
for (const reference of property.findReferencesAsNodes()) {
|
||
// The first ancestor is the property access on `this.`.
|
||
const containingNode = reference.getAncestors()[1];
|
||
// Replace all `delete this.#somePrivateVariable;` (since that is illegal on private class fields)
|
||
// and replace it with an assignment to `undefined`.
|
||
if (containingNode.getKind() === SyntaxKind.DeleteExpression) {
|
||
console.log(`Replacing delete statement on line ${reference.getStartLineNumber()}`);
|
||
// We should replace the statement, not the expression itself.
|
||
containingNode.getFirstAncestor().replaceWithText(`this.${newName} = undefined;`);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
file.saveSync();
|
||
}
|
||
// project.save();
|