Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7f71ae9

Browse files
committed
feat: add stable PrivateIdentifier base on estree spec
1 parent 763a252 commit 7f71ae9

28 files changed

+3740
-15
lines changed

packages/eslint-plugin/src/rules/naming-convention-utils/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ interface NormalizedSelector {
6060
}
6161

6262
type ValidatorFunction = (
63-
node: TSESTree.Identifier | TSESTree.Literal,
63+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
6464
modifiers?: Set<Modifiers>,
6565
) => void;
6666
type ParsedOptions = Record<SelectorsString, null | ValidatorFunction>;

packages/eslint-plugin/src/rules/naming-convention-utils/validator.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ function createValidator(
2525
type: SelectorsString,
2626
context: Context,
2727
allConfigs: NormalizedSelector[],
28-
): (node: TSESTree.Identifier | TSESTree.Literal) => void {
28+
): (
29+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
30+
) => void {
2931
// make sure the "highest priority" configs are checked first
3032
const selectorType = Selectors[type];
3133
const configs = allConfigs
@@ -70,11 +72,14 @@ function createValidator(
7072
});
7173

7274
return (
73-
node: TSESTree.Identifier | TSESTree.Literal,
75+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
7476
modifiers: Set<Modifiers> = new Set<Modifiers>(),
7577
): void => {
7678
const originalName =
77-
node.type === AST_NODE_TYPES.Identifier ? node.name : `${node.value}`;
79+
node.type === AST_NODE_TYPES.Identifier ||
80+
node.type === AST_NODE_TYPES.PrivateIdentifier
81+
? node.name
82+
: `${node.value}`;
7883

7984
// return will break the loop and stop checking configs
8085
// it is only used when the name is known to have failed or succeeded a config.
@@ -178,7 +183,7 @@ function createValidator(
178183
position: 'leading' | 'trailing',
179184
config: NormalizedSelector,
180185
name: string,
181-
node: TSESTree.Identifier | TSESTree.Literal,
186+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
182187
originalName: string,
183188
): string | null {
184189
const option =
@@ -299,7 +304,7 @@ function createValidator(
299304
position: 'prefix' | 'suffix',
300305
config: NormalizedSelector,
301306
name: string,
302-
node: TSESTree.Identifier | TSESTree.Literal,
307+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
303308
originalName: string,
304309
): string | null {
305310
const affixes = config[position];
@@ -339,7 +344,7 @@ function createValidator(
339344
function validateCustom(
340345
config: NormalizedSelector,
341346
name: string,
342-
node: TSESTree.Identifier | TSESTree.Literal,
347+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
343348
originalName: string,
344349
): boolean {
345350
const custom = config.custom;
@@ -372,7 +377,7 @@ function createValidator(
372377
function validatePredefinedFormat(
373378
config: NormalizedSelector,
374379
name: string,
375-
node: TSESTree.Identifier | TSESTree.Literal,
380+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
376381
originalName: string,
377382
): boolean {
378383
const formats = config.format;

packages/eslint-plugin/src/rules/naming-convention.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,11 +621,14 @@ function isGlobal(scope: TSESLint.Scope.Scope | null): boolean {
621621
}
622622

623623
function requiresQuoting(
624-
node: TSESTree.Identifier | TSESTree.Literal,
624+
node: TSESTree.Identifier | TSESTree.PrivateIdentifier | TSESTree.Literal,
625625
target: ScriptTarget | undefined,
626626
): boolean {
627627
const name =
628-
node.type === AST_NODE_TYPES.Identifier ? node.name : `${node.value}`;
628+
node.type === AST_NODE_TYPES.Identifier ||
629+
node.type === AST_NODE_TYPES.PrivateIdentifier
630+
? node.name
631+
: `${node.value}`;
629632
return util.requiresQuoting(name, target);
630633
}
631634

packages/eslint-plugin/src/rules/no-unsafe-assignment.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ export default util.createRule({
171171
let key: string;
172172
if (receiverProperty.computed === false) {
173173
key =
174-
receiverProperty.key.type === AST_NODE_TYPES.Identifier
174+
receiverProperty.key.type === AST_NODE_TYPES.Identifier ||
175+
receiverProperty.key.type === AST_NODE_TYPES.PrivateIdentifier
175176
? receiverProperty.key.name
176177
: String(receiverProperty.key.value);
177178
} else if (receiverProperty.key.type === AST_NODE_TYPES.Literal) {

packages/eslint-plugin/src/rules/prefer-for-of.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default util.createRule({
4343
}
4444

4545
function isMatchingIdentifier(
46-
node: TSESTree.Expression,
46+
node: TSESTree.Expression | TSESTree.PrivateIdentifier,
4747
name: string,
4848
): boolean {
4949
return node.type === AST_NODE_TYPES.Identifier && node.name === name;

packages/eslint-plugin/src/util/misc.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ function getNameFromMember(
7979
| TSESTree.TSPropertySignature,
8080
sourceCode: TSESLint.SourceCode,
8181
): string {
82-
if (member.key.type === AST_NODE_TYPES.Identifier) {
82+
if (
83+
member.key.type === AST_NODE_TYPES.Identifier ||
84+
member.key.type === AST_NODE_TYPES.PrivateIdentifier
85+
) {
8386
return member.key.name;
8487
}
8588
if (member.key.type === AST_NODE_TYPES.Literal) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Foo {
2+
#bar
3+
4+
constructor(bar) {
5+
this.#bar = name;
6+
}
7+
8+
get bar () {
9+
return this.#bar
10+
}
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Foo {
2+
private #bar: string
3+
public #bar: string
4+
static #bar: string
5+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Foo {
2+
#bar: string
3+
4+
constructor(name: string) {
5+
this.#bar = name;
6+
}
7+
8+
get bar () {
9+
return this.#bar
10+
}
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Foo {
2+
get #foo() { }
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Foo {
2+
#foo() { }
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Foo {
2+
readonly #bar: string
3+
}

packages/types/src/ast-node-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ enum AST_NODE_TYPES {
6161
NewExpression = 'NewExpression',
6262
ObjectExpression = 'ObjectExpression',
6363
ObjectPattern = 'ObjectPattern',
64+
PrivateIdentifier = 'PrivateIdentifier',
6465
Program = 'Program',
6566
Property = 'Property',
6667
RestElement = 'RestElement',

packages/types/src/ts-estree.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export type Node =
204204
| ObjectPattern
205205
| Program
206206
| Property
207+
| PrivateIdentifier
207208
| RestElement
208209
| ReturnStatement
209210
| SequenceExpression
@@ -483,6 +484,7 @@ export type PropertyName = PropertyNameComputed | PropertyNameNonComputed;
483484
export type PropertyNameComputed = Expression;
484485
export type PropertyNameNonComputed =
485486
| Identifier
487+
| PrivateIdentifier
486488
| StringLiteral
487489
| NumberLiteral;
488490
export type Statement =
@@ -654,7 +656,7 @@ interface LiteralBase extends BaseNode {
654656
/** this should not be directly used - instead use MemberExpressionComputedNameBase or MemberExpressionNonComputedNameBase */
655657
interface MemberExpressionBase extends BaseNode {
656658
object: LeftHandSideExpression;
657-
property: Expression | Identifier;
659+
property: Expression | Identifier | PrivateIdentifier;
658660
computed: boolean;
659661
optional: boolean;
660662
}
@@ -665,7 +667,7 @@ interface MemberExpressionComputedNameBase extends MemberExpressionBase {
665667
}
666668

667669
interface MemberExpressionNonComputedNameBase extends MemberExpressionBase {
668-
property: Identifier;
670+
property: Identifier | PrivateIdentifier;
669671
computed: false;
670672
}
671673

@@ -1174,6 +1176,11 @@ export interface Program extends BaseNode {
11741176
tokens?: Token[];
11751177
}
11761178

1179+
export interface PrivateIdentifier extends BaseNode {
1180+
type: AST_NODE_TYPES.PrivateIdentifier;
1181+
name: string;
1182+
}
1183+
11771184
export interface PropertyComputedName extends PropertyBase {
11781185
key: PropertyNameComputed;
11791186
computed: true;

packages/typescript-estree/src/convert.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,12 @@ export class Converter {
675675
});
676676
}
677677

678+
case SyntaxKind.PrivateIdentifier:
679+
return this.createNode<TSESTree.PrivateIdentifier>(node, {
680+
type: AST_NODE_TYPES.PrivateIdentifier,
681+
name: node.text.slice(1),
682+
});
683+
678684
case SyntaxKind.WithStatement:
679685
return this.createNode<TSESTree.WithStatement>(node, {
680686
type: AST_NODE_TYPES.WithStatement,

packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export interface EstreeToTsNodeTypes {
118118
[AST_NODE_TYPES.ObjectPattern]:
119119
| ts.ObjectLiteralExpression
120120
| ts.ObjectBindingPattern;
121+
[AST_NODE_TYPES.PrivateIdentifier]: ts.PrivateIdentifier;
121122
[AST_NODE_TYPES.Program]: ts.SourceFile;
122123
[AST_NODE_TYPES.Property]:
123124
| ts.PropertyAssignment

packages/typescript-estree/src/ts-estree/ts-nodes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export type TSNode =
6868
| ts.OmittedExpression
6969
| ts.PartiallyEmittedExpression
7070
| ts.PrefixUnaryExpression
71+
| ts.PrivateIdentifier
7172
| ts.PostfixUnaryExpression
7273
| ts.NullLiteral
7374
| ts.BooleanLiteral

packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,12 @@ tester.addFixturePatternConfig('typescript/basics', {
390390
* TODO: report this to babel
391391
*/
392392
'catch-clause-with-invalid-annotation',
393+
/**
394+
* [BABEL ERRORED, BUT TS-ESTREE DID NOT]
395+
* Private elements cannot have an accessibility modifier ('private')
396+
* TODO: Add error code from typescript
397+
*/
398+
'class-private-field-modifiers-error',
393399
],
394400
ignoreSourceType: [
395401
/**

packages/typescript-estree/tests/ast-alignment/parse.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ function parseWithBabelParser(text: string, jsx = true): any {
2323
const babel: typeof babelParser = require('@babel/parser');
2424
const plugins: ParserPlugin[] = [
2525
'classProperties',
26+
'classPrivateProperties',
27+
'classPrivateMethods',
2628
'decorators-legacy',
2729
'estree',
2830
'typescript',

packages/typescript-estree/tests/ast-alignment/utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,24 @@ export function preprocessBabylonAST(ast: BabelTypes.File): any {
241241
}
242242
}
243243
},
244+
/**
245+
* TS 3.8 private properties
246+
* https://github.com/estree/estree/blob/master/experimental/class-features.md
247+
*/
248+
ClassPrivateProperty(node) {
249+
node.type = AST_NODE_TYPES.ClassProperty;
250+
node.computed = false;
251+
node.declare = false;
252+
},
253+
ClassPrivateMethod(node) {
254+
node.type = AST_NODE_TYPES.MethodDefinition;
255+
node.computed = false;
256+
},
257+
PrivateName(node) {
258+
node.type = AST_NODE_TYPES.PrivateIdentifier;
259+
node.name = (node.id as any).name;
260+
delete node.id;
261+
},
244262
},
245263
);
246264
}

packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e
273273

274274
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/javascript/classes/class-one-method-super.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
275275

276+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/javascript/classes/class-private-field.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
277+
276278
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/javascript/classes/class-static-method.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
277279

278280
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/javascript/classes/class-static-method-named-prototype.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
@@ -1757,6 +1759,16 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e
17571759

17581760
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-multi-line-keyword-declare.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
17591761

1762+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-private-field.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
1763+
1764+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-private-field-modifiers-error.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
1765+
1766+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-private-getter.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
1767+
1768+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-private-method.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
1769+
1770+
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-readonly-private-field.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
1771+
17601772
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-with-accessibility-modifiers.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
17611773

17621774
exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-with-constructor-and-modifier.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

0 commit comments

Comments
 (0)