Skip to content
Open
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
129 changes: 48 additions & 81 deletions tsc/internal/pseudochecker/lookup.go

Large diffs are not rendered by default.

50 changes: 22 additions & 28 deletions tsc/internal/transformers/declarations/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ func createGetSymbolAccessibilityDiagnosticForNode(node *ast.Node) GetSymbolAcce
} else if ast.IsTypeParameterDeclaration(node) {
return wrapSimpleDiagnosticSelector(node, getTypeParameterConstraintVisibilityDiagnosticMessage)
} else if ast.IsExpressionWithTypeArguments(node) {
// unique node selection behavior, inline closure

return func(symbolAccessibilityResult printer.SymbolAccessibilityResult) *SymbolAccessibilityDiagnostic {
var diagnosticMessage *diagnostics.Message
// Heritage clause is written by user so it can always be named

if ast.IsClassDeclaration(node.Parent.Parent) {
// Class or Interface implemented/extended is inaccessible

if ast.IsHeritageClause(node.Parent) && node.Parent.AsHeritageClause().Token == ast.KindImplementsKeyword {
diagnosticMessage = diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1
} else {
Expand All @@ -167,7 +167,7 @@ func createGetSymbolAccessibilityDiagnosticForNode(node *ast.Node) GetSymbolAcce
}
}
} else {
// interface is inaccessible

diagnosticMessage = diagnostics.X_extends_clause_of_exported_interface_0_has_or_is_using_private_name_1
}

Expand All @@ -182,7 +182,7 @@ func createGetSymbolAccessibilityDiagnosticForNode(node *ast.Node) GetSymbolAcce
return diagnostics.Import_declaration_0_is_using_private_name_1
})
} else if ast.IsTypeAliasDeclaration(node) || ast.IsJSTypeAliasDeclaration(node) {
// unique node selection behavior, inline closure

return func(symbolAccessibilityResult printer.SymbolAccessibilityResult) *SymbolAccessibilityDiagnostic {
diagnosticMessage := selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
Expand All @@ -198,8 +198,7 @@ func createGetSymbolAccessibilityDiagnosticForNode(node *ast.Node) GetSymbolAcce
}
}
} else if ast.IsCallExpression(node) {
// JS object.defineProperty call
// unique node selection behavior, inline closure

return func(symbolAccessibilityResult printer.SymbolAccessibilityResult) *SymbolAccessibilityDiagnostic {
diagnosticMessage := selectDiagnosticBasedOnModuleName(
symbolAccessibilityResult,
Expand Down Expand Up @@ -229,11 +228,9 @@ func getVariableDeclarationTypeVisibilityDiagnosticMessage(node *ast.Node, symbo
diagnostics.Exported_variable_0_has_or_is_using_private_name_1,
)

// This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
// The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all.
} else if node.Kind == ast.KindPropertyDeclaration || node.Kind == ast.KindPropertyAccessExpression || node.Kind == ast.KindElementAccessExpression || node.Kind == ast.KindBinaryExpression || node.Kind == ast.KindPropertySignature ||
(node.Kind == ast.KindParameter && ast.HasSyntacticModifier(node.Parent, ast.ModifierFlagsPrivate)) {
// TODO(jfreeman): Deal with computed properties in error reporting.

if ast.IsStatic(node) {
return selectDiagnosticBasedOnModuleName(
symbolAccessibilityResult,
Expand All @@ -249,21 +246,20 @@ func getVariableDeclarationTypeVisibilityDiagnosticMessage(node *ast.Node, symbo
diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1,
)
} else {
// Interfaces cannot have types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2,
diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1,
)
}
}
return nil // TODO: Audit behavior - should this panic? potentially silent error state in strada
return nil
}

func getAccessorDeclarationTypeVisibilityDiagnosticMessage(node *ast.Node, symbolAccessibilityResult printer.SymbolAccessibilityResult) *diagnostics.Message {
if node.Kind == ast.KindSetAccessor {
// Getters can infer the return type from the returned expression, but setters cannot, so the
// "_from_external_module_1_but_cannot_be_named" case cannot occur.

if ast.IsStatic(node) {
return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
Expand Down Expand Up @@ -299,21 +295,21 @@ func getAccessorDeclarationTypeVisibilityDiagnosticMessage(node *ast.Node, symbo
func getReturnTypeVisibilityDiagnosticMessage(node *ast.Node, symbolAccessibilityResult printer.SymbolAccessibilityResult) *diagnostics.Message {
switch node.Kind {
case ast.KindConstructSignature:
// Interfaces cannot have return types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1,
diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0,
)
case ast.KindCallSignature:
// Interfaces cannot have return types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1,
diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0,
)
case ast.KindIndexSignature:
// Interfaces cannot have return types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1,
Expand All @@ -336,7 +332,7 @@ func getReturnTypeVisibilityDiagnosticMessage(node *ast.Node, symbolAccessibilit
diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0,
)
} else {
// Interfaces cannot have return types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1,
Expand Down Expand Up @@ -366,23 +362,23 @@ func getParameterDeclarationTypeVisibilityDiagnosticMessage(node *ast.Node, symb
)

case ast.KindConstructSignature, ast.KindConstructorType:
// Interfaces cannot have parameter types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2,
diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1,
)

case ast.KindCallSignature:
// Interfaces cannot have parameter types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2,
diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1,
)

case ast.KindIndexSignature:
// Interfaces cannot have parameter types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2,
Expand All @@ -405,7 +401,7 @@ func getParameterDeclarationTypeVisibilityDiagnosticMessage(node *ast.Node, symb
diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1,
)
} else {
// Interfaces cannot have parameter types that cannot be named

return selectDiagnosticBasedOnModuleNameNoNameCheck(
symbolAccessibilityResult,
diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2,
Expand Down Expand Up @@ -434,7 +430,7 @@ func getParameterDeclarationTypeVisibilityDiagnosticMessage(node *ast.Node, symb
}

func getTypeParameterConstraintVisibilityDiagnosticMessage(node *ast.Node, symbolAccessibilityResult printer.SymbolAccessibilityResult) *diagnostics.Message {
// Type parameter constraints are named by user so we should always be able to name it

switch node.Parent.Kind {
case ast.KindClassDeclaration:
return diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1
Expand Down Expand Up @@ -685,7 +681,7 @@ func createGetIsolatedDeclarationErrors(resolver printer.EmitResolver) func(node
if ast.IsSetAccessorDeclaration(node.Parent) {
return createAccessorTypeError(node.Parent)
}
addUndefined := resolver.RequiresAddingImplicitUndefinedUnsafe(node, nil, nil) // skip checker lock - node builder will already have one
addUndefined := resolver.RequiresAddingImplicitUndefinedUnsafe(node, nil, nil)
if !addUndefined && node.Initializer() != nil {
return createExpressionError(node.Initializer())
}
Expand All @@ -704,10 +700,8 @@ func createGetIsolatedDeclarationErrors(resolver printer.EmitResolver) func(node
if heritageClause != nil {
return createDiagnosticForNode(node, diagnostics.Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations)
}
if ast.IsPartOfTypeNode(node) || ast.IsTypeQueryNode(node) {
return createEntityInTypeNodeError(node)
}
if ast.IsEntityName(node) || ast.IsEntityNameExpression(node) {
if (ast.IsPartOfTypeNode(node) || node.Parent != nil && ast.IsTypeQueryNode(node.Parent)) &&
(ast.IsEntityName(node) || ast.IsEntityNameExpression(node)) {
return createEntityInTypeNodeError(node)
}
switch node.Kind {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
isolatedDeclarationsReturnEntityName.ts(5,17): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
isolatedDeclarationsReturnEntityName.ts(9,5): error TS9008: Method must have an explicit return type annotation with --isolatedDeclarations.


==== isolatedDeclarationsReturnEntityName.ts (2 errors) ====
// Regression for #65106: value-position entity names in returns must produce
// TS9007/TS9008 (explicit return type), not TS9039/TS9013 (private name / expression).

export const x: { a: number } = { a: 1 };
export function f() { return x; }
~
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
!!! related TS9031 isolatedDeclarationsReturnEntityName.ts:5:17: Add a return type to the function declaration.

export class C {
x = 1;
method() { return this.x; }
~~~~~~
!!! error TS9008: Method must have an explicit return type annotation with --isolatedDeclarations.
!!! related TS9034 isolatedDeclarationsReturnEntityName.ts:9:5: Add a return type to the method
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//// [tests/cases/compiler/isolatedDeclarationsReturnEntityName.ts] ////

//// [isolatedDeclarationsReturnEntityName.ts]
// Regression for #65106: value-position entity names in returns must produce
// TS9007/TS9008 (explicit return type), not TS9039/TS9013 (private name / expression).

export const x: { a: number } = { a: 1 };
export function f() { return x; }

export class C {
x = 1;
method() { return this.x; }
}


//// [isolatedDeclarationsReturnEntityName.js]
// Regression for #65106: value-position entity names in returns must produce
// TS9007/TS9008 (explicit return type), not TS9039/TS9013 (private name / expression).
export const x = { a: 1 };
export function f() { return x; }
export class C {
x = 1;
method() { return this.x; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//// [tests/cases/compiler/isolatedDeclarationsReturnEntityName.ts] ////

=== isolatedDeclarationsReturnEntityName.ts ===
// Regression for #65106: value-position entity names in returns must produce
// TS9007/TS9008 (explicit return type), not TS9039/TS9013 (private name / expression).

export const x: { a: number } = { a: 1 };
>x : Symbol(x, Decl(isolatedDeclarationsReturnEntityName.ts, 3, 12))
>a : Symbol(a, Decl(isolatedDeclarationsReturnEntityName.ts, 3, 17))
>a : Symbol(a, Decl(isolatedDeclarationsReturnEntityName.ts, 3, 33))

export function f() { return x; }
>f : Symbol(f, Decl(isolatedDeclarationsReturnEntityName.ts, 3, 41))
>x : Symbol(x, Decl(isolatedDeclarationsReturnEntityName.ts, 3, 12))

export class C {
>C : Symbol(C, Decl(isolatedDeclarationsReturnEntityName.ts, 4, 33))

x = 1;
>x : Symbol(C.x, Decl(isolatedDeclarationsReturnEntityName.ts, 6, 16))

method() { return this.x; }
>method : Symbol(C.method, Decl(isolatedDeclarationsReturnEntityName.ts, 7, 10))
>this.x : Symbol(C.x, Decl(isolatedDeclarationsReturnEntityName.ts, 6, 16))
>this : Symbol(C, Decl(isolatedDeclarationsReturnEntityName.ts, 4, 33))
>x : Symbol(C.x, Decl(isolatedDeclarationsReturnEntityName.ts, 6, 16))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//// [tests/cases/compiler/isolatedDeclarationsReturnEntityName.ts] ////

=== isolatedDeclarationsReturnEntityName.ts ===
// Regression for #65106: value-position entity names in returns must produce
// TS9007/TS9008 (explicit return type), not TS9039/TS9013 (private name / expression).

export const x: { a: number } = { a: 1 };
>x : { a: number; }
>a : number
>{ a: 1 } : { a: number; }
>a : number
>1 : 1

export function f() { return x; }
>f : () => { a: number; }
>x : { a: number; }

export class C {
>C : C

x = 1;
>x : number
>1 : 1

method() { return this.x; }
>method : () => number
>this.x : number
>this : this
>x : number
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @declaration: true
// @isolatedDeclarations: true
// @declarationMap: false
// @target: ESNext

// Regression for #65106: value-position entity names in returns must produce
// TS9007/TS9008 (explicit return type), not TS9039/TS9013 (private name / expression).

export const x: { a: number } = { a: 1 };
export function f() { return x; }

export class C {
x = 1;
method() { return this.x; }
}