-
Notifications
You must be signed in to change notification settings - Fork 13.2k
ES private class elements #42458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ES private class elements #42458
Changes from 1 commit
e3a3fb8
4ab27a2
6977b9f
bc8c07e
2760ed8
04af85d
f048d72
f8cfb81
4aa4c3b
0ac1271
7da5bd9
e133f60
aa5dd8a
a3889a7
8952caa
dee87bb
aec7e9b
f3bbf0f
a1b59cd
6b74498
d51f6cd
c175770
4301af5
3a056b2
95df2d1
590124e
219ea83
25da8ca
a2228be
ff4f737
704727c
73925dc
67fd38d
45c2a41
356b91d
b391464
5ebb3d6
7006c09
b876613
31a8c00
9219e99
5a27a32
964fc27
d2ab6fc
23f6c67
374e6f3
62b4f2f
b2a692d
363041e
64757e0
68a7f80
7e7b0b1
30c7f69
c924058
e65116f
4748c87
09a5aae
497e47f
294cc48
027bdb3
7bbc944
dd526e7
f6ecfab
6c3f661
ef69c6c
2a646ed
d8136f7
fbd749c
f96eafe
2de8a43
7490a36
c273258
1addbb3
c461b92
a61fd5f
89f746a
ff24636
a60e429
f5816ab
3b62d3c
7d8a2b9
d0d2055
93a7ca3
6da2cdd
30805b7
8d77a8e
8078ae0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Signed-off-by: Kubilay Kahveci <[email protected]>
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,21 +30,25 @@ namespace ts { | |
|
|
||
| interface PrivateIdentifierInstanceMethod { | ||
| placement: PrivateIdentifierPlacement.InstanceMethod; | ||
| weakSetName: Identifier; | ||
| functionName: Identifier; | ||
| } | ||
|
|
||
| interface PrivateIdentifierInstanceGetterOnly { | ||
| placement: PrivateIdentifierPlacement.InstanceGetterOnly; | ||
| weakSetName: Identifier; | ||
| getterName: Identifier; | ||
| } | ||
|
|
||
| interface PrivateIdentifierInstanceSetterOnly { | ||
| placement: PrivateIdentifierPlacement.InstanceSetterOnly; | ||
| weakSetName: Identifier; | ||
| setterName: Identifier; | ||
| } | ||
|
|
||
| interface PrivateIdentifierInstanceGetterAndSetter { | ||
| placement: PrivateIdentifierPlacement.InstanceGetterAndSetter; | ||
| weakSetName: Identifier; | ||
| getterName: Identifier; | ||
| setterName: Identifier; | ||
| } | ||
|
|
@@ -54,7 +58,6 @@ namespace ts { | |
| * Used for prefixing generated variable names. | ||
| */ | ||
| className: string; | ||
| hasPrivateMethods: boolean; | ||
| /** | ||
| * Used for brand check on private methods. | ||
| */ | ||
|
|
@@ -325,14 +328,14 @@ namespace ts { | |
| case PrivateIdentifierPlacement.InstanceMethod: | ||
| return context.getEmitHelperFactory().createClassPrivateMethodGetHelper( | ||
| receiver, | ||
| getPrivateIdentifierEnvironment().weakSetName, | ||
| info.weakSetName, | ||
| info.functionName | ||
| ); | ||
| case PrivateIdentifierPlacement.InstanceGetterOnly: | ||
| case PrivateIdentifierPlacement.InstanceGetterAndSetter: | ||
| return context.getEmitHelperFactory().createClassPrivateAccessorGetHelper( | ||
| receiver, | ||
| getPrivateIdentifierEnvironment().weakSetName, | ||
| info.weakSetName, | ||
| info.getterName | ||
| ); | ||
| case PrivateIdentifierPlacement.InstanceSetterOnly: | ||
|
|
@@ -550,7 +553,7 @@ namespace ts { | |
| case PrivateIdentifierPlacement.InstanceGetterAndSetter: | ||
| return context.getEmitHelperFactory().createClassPrivateAccessorSetHelper( | ||
| receiver, | ||
| getPrivateIdentifierEnvironment().weakSetName, | ||
| info.weakSetName, | ||
| info.setterName, | ||
| right | ||
| ); | ||
|
|
@@ -571,6 +574,10 @@ namespace ts { | |
| if (name && isIdentifier(name)) { | ||
| getPrivateIdentifierEnvironment().className = name.escapedText as string; | ||
| } | ||
|
|
||
| if (some(getPrivateInstanceMethods(node))) { | ||
| getPrivateIdentifierEnvironment().weakSetName = createHoistedVariableForClass("instances"); | ||
| } | ||
| } | ||
|
|
||
| const result = isClassDeclaration(node) ? | ||
|
|
@@ -588,6 +595,13 @@ namespace ts { | |
| return isPropertyDeclaration(node) || (shouldTransformPrivateElements && node.name && isPrivateIdentifier(node.name)); | ||
| } | ||
|
|
||
| function getPrivateInstanceMethods(node: ClassLikeDeclaration) { | ||
| return filter( | ||
|
||
| [...getMethods(node, /*isStatic*/ false), ...getAccessors(node, /*isStatic*/ false)], | ||
| method => isPrivateIdentifier(method.name) | ||
| ); | ||
| } | ||
|
|
||
| function visitClassDeclaration(node: ClassDeclaration) { | ||
| if (!forEach(node.members, doesClassElementNeedTransform)) { | ||
| return visitEachChild(node, visitor, context); | ||
|
|
@@ -705,7 +719,9 @@ namespace ts { | |
| } | ||
| } | ||
|
|
||
| createBrandCheckWeakSetForPrivateMethods(); | ||
| if (some(getPrivateInstanceMethods(node))) { | ||
| createBrandCheckWeakSetForPrivateMethods(); | ||
| } | ||
| } | ||
|
|
||
| const members: ClassElement[] = []; | ||
|
|
@@ -718,17 +734,9 @@ namespace ts { | |
| } | ||
|
|
||
| function createBrandCheckWeakSetForPrivateMethods() { | ||
| const env = getPrivateIdentifierEnvironment(); | ||
| if (!env.hasPrivateMethods) { | ||
| return; | ||
| } | ||
|
|
||
| const weakSetName = createHoistedVariableForClass("instances"); | ||
| env.weakSetName = weakSetName; | ||
|
|
||
| getPendingExpressions().push( | ||
| factory.createAssignment( | ||
| env.weakSetName, | ||
| getPrivateIdentifierEnvironment().weakSetName, | ||
| factory.createNewExpression( | ||
| factory.createIdentifier("WeakSet"), | ||
| /*typeArguments*/ undefined, | ||
|
|
@@ -784,10 +792,7 @@ namespace ts { | |
| properties = filter(properties, property => !!property.initializer || isPrivateIdentifier(property.name)); | ||
| } | ||
|
|
||
| const privateMethods = filter( | ||
| [...getMethods(node, /*isStatic*/ false), ...getAccessors(node, /*isStatic*/ false)], | ||
| method => isPrivateIdentifier(method.name) | ||
| ); | ||
| const privateMethods = getPrivateInstanceMethods(node); | ||
| const needsConstructorBody = some(properties) || some(privateMethods); | ||
|
|
||
| // Only generate synthetic constructor when there are property initializers to move. | ||
|
|
@@ -1081,7 +1086,6 @@ namespace ts { | |
| if (!currentPrivateIdentifierEnvironment) { | ||
| currentPrivateIdentifierEnvironment = { | ||
| className: "", | ||
| hasPrivateMethods: false, | ||
| weakSetName: factory.createUniqueName("_instances", GeneratedIdentifierFlags.Optimistic), | ||
|
||
| identifiers: new Map() | ||
| }; | ||
|
|
@@ -1096,6 +1100,7 @@ namespace ts { | |
|
|
||
| function addPrivateIdentifierToEnvironment(node: PrivateClassElementDeclaration) { | ||
| const text = getTextOfPropertyName(node.name) as string; | ||
| const { weakSetName } = getPrivateIdentifierEnvironment(); | ||
| let info: PrivateIdentifierInfo; | ||
| const assignmentExpressions: Expression[] = []; | ||
|
|
||
|
|
@@ -1118,10 +1123,9 @@ namespace ts { | |
| else if (isMethodDeclaration(node)) { | ||
| info = { | ||
| placement: PrivateIdentifierPlacement.InstanceMethod, | ||
| functionName: createHoistedVariableForPrivateName(text) | ||
| weakSetName, | ||
| functionName: createHoistedVariableForPrivateName(text), | ||
| }; | ||
|
|
||
| getPrivateIdentifierEnvironment().hasPrivateMethods = true; | ||
| } | ||
| else if (isAccessor(node)) { | ||
| const previousInfo = findPreviousAccessorInfo(node); | ||
|
|
@@ -1132,13 +1136,15 @@ namespace ts { | |
| if (previousInfo?.placement === PrivateIdentifierPlacement.InstanceSetterOnly) { | ||
| info = { | ||
| placement: PrivateIdentifierPlacement.InstanceGetterAndSetter, | ||
| weakSetName, | ||
| getterName, | ||
| setterName: previousInfo.setterName | ||
| }; | ||
| } | ||
| else { | ||
| info = { | ||
| placement: PrivateIdentifierPlacement.InstanceGetterOnly, | ||
| weakSetName, | ||
| getterName | ||
| }; | ||
| } | ||
|
|
@@ -1149,19 +1155,19 @@ namespace ts { | |
| if (previousInfo?.placement === PrivateIdentifierPlacement.InstanceGetterOnly) { | ||
| info = { | ||
| placement: PrivateIdentifierPlacement.InstanceGetterAndSetter, | ||
| weakSetName, | ||
| setterName, | ||
| getterName: previousInfo.getterName | ||
| }; | ||
| } | ||
| else { | ||
| info = { | ||
| placement: PrivateIdentifierPlacement.InstanceSetterOnly, | ||
| weakSetName, | ||
| setterName | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| getPrivateIdentifierEnvironment().hasPrivateMethods = true; | ||
| } | ||
| else { | ||
| return; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise you'll get the escaped name which turns
__Foointo___Foo.