Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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.emitPropertyName(node.Right)
Comment thread
weswigham marked this conversation as resolved.
Outdated
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