Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _packages/native-preview/src/ast/ast.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export interface PrivateIdentifier extends PrimaryExpressionBase {
export interface QualifiedName extends NodeBase {
readonly kind: SyntaxKind.QualifiedName;
readonly left: EntityName;
readonly right: Identifier;
readonly right: MemberName;
}
export interface ComputedPropertyName extends NodeBase {
readonly kind: SyntaxKind.ComputedPropertyName;
Expand Down
4 changes: 2 additions & 2 deletions _packages/native-preview/src/ast/factory.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1673,7 +1673,7 @@ export function createPrivateIdentifier(text: string): PrivateIdentifier {
}) as unknown as PrivateIdentifier;
}

export function createQualifiedName(left: EntityName, right: Identifier): QualifiedName {
export function createQualifiedName(left: EntityName, right: MemberName): QualifiedName {
return new NodeObject(SyntaxKind.QualifiedName, {
left,
right,
Expand Down Expand Up @@ -3105,7 +3105,7 @@ export function createJSDocPropertyTag(tagName: Identifier, name: EntityName, is
}) as unknown as JSDocPropertyTag;
}

export function updateQualifiedName(node: QualifiedName, left: EntityName, right: Identifier): QualifiedName {
export function updateQualifiedName(node: QualifiedName, left: EntityName, right: MemberName): QualifiedName {
return node.left !== left || node.right !== right ? createQualifiedName(left, right) : node;
}

Expand Down
2 changes: 1 addition & 1 deletion _packages/native-preview/src/ast/visitor.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ type VisitEachChildFunction = (node: any, visitor: Visitor) => Node;
const visitEachChildTable: Record<number, VisitEachChildFunction> = {
[SyntaxKind.QualifiedName]: (node: QualifiedName, visitor: Visitor): QualifiedName => {
const _left = visitNode(node.left, visitor, isEntityName);
const _right = visitNode(node.right, visitor, isIdentifier);
const _right = visitNode(node.right, visitor, isMemberName);
return updateQualifiedName(node, _left, _right);
},
[SyntaxKind.ComputedPropertyName]: (node: ComputedPropertyName, visitor: Visitor): ComputedPropertyName => {
Expand Down
2 changes: 1 addition & 1 deletion _scripts/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,7 @@
},
{
"name": "Right",
"type": "Identifier"
"type": "MemberName"
}
]
},
Expand Down
6 changes: 3 additions & 3 deletions internal/ast/ast_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions internal/diagnostics/diagnostics_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions internal/diagnostics/extraDiagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@
"category": "Error",
"code": 5002
},
"Declaration emit elides private members, but '{0}' refers to a private member. Write an explicit type here.": {
"category": "Error",
"code": 7080
},
"Binding elements with initializers can't be exported directly with --isolatedDeclarations.": {
"category": "Error",
"code": 9019
Expand Down
12 changes: 6 additions & 6 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func ParseIsolatedEntityName(text string) *ast.EntityName {
defer putParser(p)
p.initializeState(ast.SourceFileParseOptions{}, text, core.ScriptKindJS)
p.nextToken()
entityName := p.parseEntityName(true, nil)
entityName := p.parseEntityName(true, false, nil)
return core.IfElse(p.token == ast.KindEndOfFile && len(p.diagnostics) == 0, entityName, nil)
}

Expand Down Expand Up @@ -2350,7 +2350,7 @@ func (p *Parser) parseModuleReference() *ast.Node {
if p.token == ast.KindRequireKeyword && p.lookAhead((*Parser).nextTokenIsOpenParen) {
return p.parseExternalModuleReference()
}
return p.parseEntityName(false /*allowReservedWords*/, nil /*diagnosticMessage*/)
return p.parseEntityName(false /*allowReservedWords*/, false /*allowPrivateName*/, nil /*diagnosticMessage*/)
}

func (p *Parser) parseExternalModuleReference() *ast.Node {
Expand Down Expand Up @@ -2941,10 +2941,10 @@ func (p *Parser) parseTypeReference() *ast.Node {
}

func (p *Parser) parseEntityNameOfTypeReference() *ast.Node {
return p.parseEntityName(true /*allowReservedWords*/, diagnostics.Type_expected)
return p.parseEntityName(true /*allowReservedWords*/, false /*allowPrivateName*/, diagnostics.Type_expected)
}

func (p *Parser) parseEntityName(allowReservedWords bool, diagnosticMessage *diagnostics.Message) *ast.Node {
func (p *Parser) parseEntityName(allowReservedWords bool, allowPrivateName bool, diagnosticMessage *diagnostics.Message) *ast.Node {
pos := p.nodePos()
var entity *ast.Node
if allowReservedWords {
Expand All @@ -2958,7 +2958,7 @@ func (p *Parser) parseEntityName(allowReservedWords bool, diagnosticMessage *dia
// `typeArguments` to report it as a grammar error in the checker.
break
}
entity = p.finishNode(p.factory.NewQualifiedName(entity, p.parseRightSideOfDot(allowReservedWords, false /*allowPrivateIdentifiers*/, true /*allowUnicodeEscapeSequenceInIdentifierName*/)), pos)
entity = p.finishNode(p.factory.NewQualifiedName(entity, p.parseRightSideOfDot(allowReservedWords, allowPrivateName, true /*allowUnicodeEscapeSequenceInIdentifierName*/)), pos)
}
return entity
}
Expand Down Expand Up @@ -3157,7 +3157,7 @@ func (p *Parser) parseImportAttributes(token ast.Kind, skipKeyword bool) *ast.No
func (p *Parser) parseTypeQuery() *ast.Node {
pos := p.nodePos()
p.parseExpected(ast.KindTypeOfKeyword)
entityName := p.parseEntityName(true /*allowReservedWords*/, nil)
entityName := p.parseEntityName(true /*allowReservedWords*/, true /*allowPrivateName*/, nil)
// Make sure we perform ASI to prevent parsing the next line's type arguments as part of an instantiation expression
var typeArguments *ast.NodeList
if !p.hasPrecedingLineBreak() {
Expand Down
2 changes: 1 addition & 1 deletion internal/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ func (p *Printer) emitQualifiedName(node *ast.QualifiedName) {
state := p.enterNode(node.AsNode())
p.emitEntityName(node.Left)
p.writePunctuation(".")
p.emitIdentifierName(node.Right.AsIdentifier())
p.emitMemberName(node.Right)
p.exitNode(node.AsNode(), state)
}

Expand Down
5 changes: 5 additions & 0 deletions internal/transformers/declarations/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,11 @@ func (tx *DeclarationTransformer) visitDeclarationSubtree(input *ast.Node) *ast.
case ast.KindTypeQuery:
tx.checkEntityNameVisibility(input.AsTypeQueryNode().ExprName, tx.enclosingDeclaration)
result = tx.Visitor().VisitEachChild(input)
case ast.KindQualifiedName:
if input.AsQualifiedName().Right.Kind == ast.KindPrivateIdentifier {
tx.state.addDiagnostic(createDiagnosticForNode(input, diagnostics.Declaration_emit_elides_private_members_but_0_refers_to_a_private_member_Write_an_explicit_type_here, input.AsQualifiedName().Right.Text()))
}
result = tx.Visitor().VisitEachChild(input)
case ast.KindTupleType:
result = tx.Visitor().VisitEachChild(input)
if result != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
declarationEmitPrivateNameInTypeQuery.ts(16,15): error TS7080: Declaration emit elides private members, but '#a' refers to a private member. Write an explicit type here.
declarationEmitPrivateNameInTypeQuery.ts(31,26): error TS7080: Declaration emit elides private members, but '#b' refers to a private member. Write an explicit type here.


==== declarationEmitPrivateNameInTypeQuery.ts (2 errors) ====
export class C1 {
#a = 1;

static #b = "";

#c() {
return 1 as const;
}

get #d() {
return new Date();
}

["#a"] = true;

a: typeof this.#a = 1;
~~~~~~~
!!! error TS7080: Declaration emit elides private members, but '#a' refers to a private member. Write an explicit type here.

test1(a: C1) {
const b: typeof a.#a = 1;
const c: typeof C1.#b = "";

return [b, c] as const;
}

}

export class C2 {
#a = 1;

static #b = "";
public prop!: typeof C2.#b;
~~~~~
!!! error TS7080: Declaration emit elides private members, but '#b' refers to a private member. Write an explicit type here.

test1() {
class C {
test1(a: C2): typeof a.#a {
return 1;
}
}
return new C().test1(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//// [tests/cases/compiler/declarationEmitPrivateNameInTypeQuery.ts] ////

//// [declarationEmitPrivateNameInTypeQuery.ts]
export class C1 {
#a = 1;

static #b = "";

#c() {
return 1 as const;
}

get #d() {
return new Date();
}

["#a"] = true;

a: typeof this.#a = 1;

test1(a: C1) {
const b: typeof a.#a = 1;
const c: typeof C1.#b = "";

return [b, c] as const;
}

}

export class C2 {
#a = 1;

static #b = "";
public prop!: typeof C2.#b;

test1() {
class C {
test1(a: C2): typeof a.#a {
return 1;
}
}
return new C().test1(this);
}
}

//// [declarationEmitPrivateNameInTypeQuery.js]
export class C1 {
#a = 1;
static #b = "";
#c() {
return 1;
}
get #d() {
return new Date();
}
["#a"] = true;
a = 1;
test1(a) {
const b = 1;
const c = "";
return [b, c];
}
}
export class C2 {
#a = 1;
static #b = "";
prop;
test1() {
class C {
test1(a) {
return 1;
}
}
return new C().test1(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//// [tests/cases/compiler/declarationEmitPrivateNameInTypeQuery.ts] ////

=== declarationEmitPrivateNameInTypeQuery.ts ===
export class C1 {
>C1 : Symbol(C1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 0, 0))

#a = 1;
>#a : Symbol(C1.#a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 0, 17))

static #b = "";
>#b : Symbol(C1.#b, Decl(declarationEmitPrivateNameInTypeQuery.ts, 1, 11))

#c() {
>#c : Symbol(C1.#c, Decl(declarationEmitPrivateNameInTypeQuery.ts, 3, 19))

return 1 as const;
>const : Symbol(const)
}

get #d() {
>#d : Symbol(C1.#d, Decl(declarationEmitPrivateNameInTypeQuery.ts, 7, 5))

return new Date();
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 2 more)
}

["#a"] = true;
>["#a"] : Symbol(C1["#a"], Decl(declarationEmitPrivateNameInTypeQuery.ts, 11, 5))
>"#a" : Symbol(C1["#a"], Decl(declarationEmitPrivateNameInTypeQuery.ts, 11, 5))

a: typeof this.#a = 1;
>a : Symbol(C1.a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 13, 18))
>this.#a : Symbol(C1.#a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 0, 17))
>this : Symbol(C1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 0, 0))

test1(a: C1) {
>test1 : Symbol(C1.test1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 15, 26))
>a : Symbol(a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 17, 10))
>C1 : Symbol(C1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 0, 0))

const b: typeof a.#a = 1;
>b : Symbol(b, Decl(declarationEmitPrivateNameInTypeQuery.ts, 18, 13))
>a.#a : Symbol(C1.#a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 0, 17))
>a : Symbol(a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 17, 10))

const c: typeof C1.#b = "";
>c : Symbol(c, Decl(declarationEmitPrivateNameInTypeQuery.ts, 19, 13))
>C1.#b : Symbol(C1.#b, Decl(declarationEmitPrivateNameInTypeQuery.ts, 1, 11))
>C1 : Symbol(C1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 0, 0))

return [b, c] as const;
>b : Symbol(b, Decl(declarationEmitPrivateNameInTypeQuery.ts, 18, 13))
>c : Symbol(c, Decl(declarationEmitPrivateNameInTypeQuery.ts, 19, 13))
>const : Symbol(const)
}

}

export class C2 {
>C2 : Symbol(C2, Decl(declarationEmitPrivateNameInTypeQuery.ts, 24, 1))

#a = 1;
>#a : Symbol(C2.#a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 26, 17))

static #b = "";
>#b : Symbol(C2.#b, Decl(declarationEmitPrivateNameInTypeQuery.ts, 27, 11))

public prop!: typeof C2.#b;
>prop : Symbol(C2.prop, Decl(declarationEmitPrivateNameInTypeQuery.ts, 29, 19))
>C2.#b : Symbol(C2.#b, Decl(declarationEmitPrivateNameInTypeQuery.ts, 27, 11))
>C2 : Symbol(C2, Decl(declarationEmitPrivateNameInTypeQuery.ts, 24, 1))

test1() {
>test1 : Symbol(C2.test1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 30, 31))

class C {
>C : Symbol(C, Decl(declarationEmitPrivateNameInTypeQuery.ts, 32, 13))

test1(a: C2): typeof a.#a {
>test1 : Symbol(C.test1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 33, 17))
>a : Symbol(a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 34, 18))
>C2 : Symbol(C2, Decl(declarationEmitPrivateNameInTypeQuery.ts, 24, 1))
>a.#a : Symbol(C2.#a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 26, 17))
>a : Symbol(a, Decl(declarationEmitPrivateNameInTypeQuery.ts, 34, 18))

return 1;
}
}
return new C().test1(this);
>new C().test1 : Symbol(C.test1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 33, 17))
>C : Symbol(C, Decl(declarationEmitPrivateNameInTypeQuery.ts, 32, 13))
>test1 : Symbol(C.test1, Decl(declarationEmitPrivateNameInTypeQuery.ts, 33, 17))
>this : Symbol(C2, Decl(declarationEmitPrivateNameInTypeQuery.ts, 24, 1))
}
}
Loading