Skip to content

Commit

Permalink
Process only visible private fields when redeclaring
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Apr 12, 2020
1 parent 808445b commit 995a6be
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 175 deletions.
82 changes: 39 additions & 43 deletions packages/babel-helper-create-class-features-plugin/src/fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,35 @@ import optimiseCall from "@babel/helper-optimise-call-expression";

import * as ts from "./typescript";

export function buildPrivateNamesMap(privateNamesMap, props, depth) {
export function buildPrivateNamesMap(props) {
const privateNamesMap = new Map();
for (const prop of props) {
if (prop.isPrivate()) {
const isMethod = !prop.isProperty();
const isInstance = !prop.node.static;
const isPrivate = prop.isPrivate();
const isMethod = !prop.isProperty();
const isInstance = !prop.node.static;
if (isPrivate) {
const { name } = prop.node.key.id;

let update = privateNamesMap.get(name);
if (!update || update.depth !== depth) {
update = {
id: prop.scope.generateUidIdentifier(name),
static: !isInstance,
method: isMethod,
depth,
};
privateNamesMap.set(name, update);
}

const update = privateNamesMap.has(name)
? privateNamesMap.get(name)
: {
id: prop.scope.generateUidIdentifier(name),
static: !isInstance,
method: isMethod,
};
if (prop.node.kind === "get") {
update.getId = prop.scope.generateUidIdentifier(`get_${name}`);
} else if (prop.node.kind === "set") {
update.setId = prop.scope.generateUidIdentifier(`set_${name}`);
} else if (prop.node.kind === "method") {
update.methodId = prop.scope.generateUidIdentifier(name);
}
privateNamesMap.set(name, update);
}
}
return privateNamesMap;
}

export function buildPrivateNamesNodes(
privateNamesMap,
loose,
state,
privateDepth,
) {
export function buildPrivateNamesNodes(privateNamesMap, loose, state) {
const initNodes = [];

for (const [name, value] of privateNamesMap) {
Expand All @@ -51,16 +45,7 @@ export function buildPrivateNamesNodes(
// In spec mode, only instance fields need a "private name" initializer
// because static fields are directly assigned to a variable in the
// buildPrivateStaticFieldInitSpec function.
const {
id,
static: isStatic,
method: isMethod,
getId,
setId,
depth,
} = value;
if (depth !== privateDepth) continue;

const { id, static: isStatic, method: isMethod, getId, setId } = value;
const isAccessor = getId || setId;
if (loose) {
initNodes.push(
Expand Down Expand Up @@ -100,24 +85,36 @@ const privateNameVisitor = {
const { privateNamesMap } = this;
const body = path.get("body.body");

const visiblePrivateNames = new Map(privateNamesMap);
for (const prop of body) {
if (!prop.isPrivate()) {
continue;
}
if (!privateNamesMap.has(prop.node.key.id.name)) continue;
if (!prop.isPrivate()) continue;
visiblePrivateNames.delete(prop.node.key.id.name);
}

// This class redeclares the private name.
// So, we can only evaluate the things in the outer scope.
path.traverse(privateNameInnerVisitor, this);
path.skip();
break;
// If the class doesn't redeclare any private fields, we can continue with
// our overall traversal.
if (visiblePrivateNames.size === privateNamesMap.size) {
return;
}

// This class redeclares some private name. We need to process the outer
// environment with access to all the outer private, then we can process
// the inner environment with only the still-visible outer privates.
path.traverse(privateNameNestedVisitor, this);
path.traverse(privateNameVisitor, {
...this,
privateNamesMap: visiblePrivateNames,
});

// We'll eventually this this class node again with the overall Class
// Features visitor, which'll process the redeclared privates.
path.skip();
},
};

// Traverses the outer portion of a class, without touching the class's inner
// scope, for private names.
const privateNameInnerVisitor = traverse.visitors.merge([
const privateNameNestedVisitor = traverse.visitors.merge([
{
PrivateName: privateNameVisitor.PrivateName,
},
Expand Down Expand Up @@ -278,7 +275,6 @@ export function transformPrivateNamesUsage(
loose,
state,
) {
if (!privateNamesMap.size) return;
const body = path.get("body");

if (loose) {
Expand Down

0 comments on commit 995a6be

Please sign in to comment.