Files
react-native-devtools-frontend/scripts/migration/class-fields/migrate.js
T
Tim van der Lippe c2675ef35a Update migration script for private class methods
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>
2021-12-15 12:16:27 +00:00

67 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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();