• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import {
2    addRelatedInfo,
3    AnnotationPropertyDeclaration,
4    ArrayLiteralExpression,
5    ArrowFunction,
6    assertType,
7    BindingElement,
8    CallSignatureDeclaration,
9    ClassExpression,
10    ComputedPropertyName,
11    ConstructorDeclaration,
12    ConstructSignatureDeclaration,
13    createDiagnosticForNode,
14    Debug,
15    Declaration,
16    DeclarationName,
17    DiagnosticMessage,
18    Diagnostics,
19    DiagnosticWithLocation,
20    EmitResolver,
21    ExportAssignment,
22    Expression,
23    ExpressionWithTypeArguments,
24    findAncestor,
25    FunctionDeclaration,
26    FunctionExpression,
27    GetAccessorDeclaration,
28    getAllAccessorDeclarations,
29    getNameOfDeclaration,
30    getTextOfNode,
31    hasSyntacticModifier,
32    ImportEqualsDeclaration,
33    IndexSignatureDeclaration,
34    isAnnotationPropertyDeclaration,
35    isAsExpression,
36    isBindingElement,
37    isCallSignatureDeclaration,
38    isClassDeclaration,
39    isConstructorDeclaration,
40    isConstructSignatureDeclaration,
41    isExportAssignment,
42    isExpressionWithTypeArguments,
43    isFunctionDeclaration,
44    isGetAccessor,
45    isHeritageClause,
46    isImportEqualsDeclaration,
47    isIndexSignatureDeclaration,
48    isJSDocTypeAlias,
49    isMethodDeclaration,
50    isMethodSignature,
51    isParameter,
52    isParameterPropertyDeclaration,
53    isParenthesizedExpression,
54    isPropertyAccessExpression,
55    isPropertyDeclaration,
56    isPropertySignature,
57    isSetAccessor,
58    isStatement,
59    isStatic,
60    isTypeAliasDeclaration,
61    isTypeAssertionExpression,
62    isTypeParameterDeclaration,
63    isVariableDeclaration,
64    JSDocCallbackTag,
65    JSDocEnumTag,
66    JSDocTypedefTag,
67    MethodDeclaration,
68    MethodSignature,
69    ModifierFlags,
70    NamedDeclaration,
71    Node,
72    ParameterDeclaration,
73    PropertyAccessExpression,
74    PropertyAssignment,
75    PropertyDeclaration,
76    PropertySignature,
77    QualifiedName,
78    SetAccessorDeclaration,
79    ShorthandPropertyAssignment,
80    SpreadAssignment,
81    SpreadElement,
82    SymbolAccessibility,
83    SymbolAccessibilityResult,
84    SyntaxKind,
85    TypeAliasDeclaration,
86    TypeParameterDeclaration,
87    VariableDeclaration,
88} from "../../_namespaces/ts";
89
90/** @internal */
91export type GetSymbolAccessibilityDiagnostic = (symbolAccessibilityResult: SymbolAccessibilityResult) => (SymbolAccessibilityDiagnostic | undefined);
92
93/** @internal */
94export interface SymbolAccessibilityDiagnostic {
95    errorNode: Node;
96    diagnosticMessage: DiagnosticMessage;
97    typeName?: DeclarationName | QualifiedName;
98}
99
100/** @internal */
101export type DeclarationDiagnosticProducing =
102    | VariableDeclaration
103    | PropertyDeclaration
104    | AnnotationPropertyDeclaration
105    | PropertySignature
106    | BindingElement
107    | SetAccessorDeclaration
108    | GetAccessorDeclaration
109    | ConstructSignatureDeclaration
110    | CallSignatureDeclaration
111    | MethodDeclaration
112    | MethodSignature
113    | FunctionDeclaration
114    | ParameterDeclaration
115    | TypeParameterDeclaration
116    | ExpressionWithTypeArguments
117    | ImportEqualsDeclaration
118    | TypeAliasDeclaration
119    | ConstructorDeclaration
120    | IndexSignatureDeclaration
121    | PropertyAccessExpression
122    | JSDocTypedefTag
123    | JSDocCallbackTag
124    | JSDocEnumTag;
125
126/** @internal */
127export function canProduceDiagnostics(node: Node): node is DeclarationDiagnosticProducing {
128    return isVariableDeclaration(node) ||
129        isPropertyDeclaration(node) ||
130        isAnnotationPropertyDeclaration(node) ||
131        isPropertySignature(node) ||
132        isBindingElement(node) ||
133        isSetAccessor(node) ||
134        isGetAccessor(node) ||
135        isConstructSignatureDeclaration(node) ||
136        isCallSignatureDeclaration(node) ||
137        isMethodDeclaration(node) ||
138        isMethodSignature(node) ||
139        isFunctionDeclaration(node) ||
140        isParameter(node) ||
141        isTypeParameterDeclaration(node) ||
142        isExpressionWithTypeArguments(node) ||
143        isImportEqualsDeclaration(node) ||
144        isTypeAliasDeclaration(node) ||
145        isConstructorDeclaration(node) ||
146        isIndexSignatureDeclaration(node) ||
147        isPropertyAccessExpression(node) ||
148        isJSDocTypeAlias(node);
149}
150
151/** @internal */
152export function createGetSymbolAccessibilityDiagnosticForNodeName(node: DeclarationDiagnosticProducing) {
153    if (isSetAccessor(node) || isGetAccessor(node)) {
154        return getAccessorNameVisibilityError;
155    }
156    else if (isMethodSignature(node) || isMethodDeclaration(node)) {
157        return getMethodNameVisibilityError;
158    }
159    else {
160        return createGetSymbolAccessibilityDiagnosticForNode(node);
161    }
162    function getAccessorNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) {
163        const diagnosticMessage = getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
164        return diagnosticMessage !== undefined ? {
165            diagnosticMessage,
166            errorNode: node,
167            typeName: (node as NamedDeclaration).name
168        } : undefined;
169    }
170
171    function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) {
172        if (isStatic(node)) {
173            return symbolAccessibilityResult.errorModuleName ?
174                symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
175                    Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
176                    Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
177                Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
178        }
179        else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
180            return symbolAccessibilityResult.errorModuleName ?
181                symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
182                    Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
183                    Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
184                Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
185        }
186        else {
187            return symbolAccessibilityResult.errorModuleName ?
188                Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
189                Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
190        }
191    }
192
193    function getMethodNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined {
194        const diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
195        return diagnosticMessage !== undefined ? {
196            diagnosticMessage,
197            errorNode: node,
198            typeName: (node as NamedDeclaration).name
199        } : undefined;
200    }
201
202    function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) {
203        if (isStatic(node)) {
204            return symbolAccessibilityResult.errorModuleName ?
205                symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
206                    Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
207                    Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
208                Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1;
209        }
210        else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
211            return symbolAccessibilityResult.errorModuleName ?
212                symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
213                    Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
214                    Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
215                Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1;
216        }
217        else {
218            return symbolAccessibilityResult.errorModuleName ?
219                Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
220                Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1;
221        }
222    }
223}
224
225/** @internal */
226export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationDiagnosticProducing): GetSymbolAccessibilityDiagnostic {
227    if (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isAnnotationPropertyDeclaration(node) ||
228        isPropertyAccessExpression(node) || isBindingElement(node) || isConstructorDeclaration(node)) {
229        return getVariableDeclarationTypeVisibilityError;
230    }
231    else if (isSetAccessor(node) || isGetAccessor(node)) {
232        return getAccessorDeclarationTypeVisibilityError;
233    }
234    else if (isConstructSignatureDeclaration(node) || isCallSignatureDeclaration(node) || isMethodDeclaration(node) || isMethodSignature(node) || isFunctionDeclaration(node) || isIndexSignatureDeclaration(node)) {
235        return getReturnTypeVisibilityError;
236    }
237    else if (isParameter(node)) {
238        if (isParameterPropertyDeclaration(node, node.parent) && hasSyntacticModifier(node.parent, ModifierFlags.Private)) {
239            return getVariableDeclarationTypeVisibilityError;
240        }
241        return getParameterDeclarationTypeVisibilityError;
242    }
243    else if (isTypeParameterDeclaration(node)) {
244        return getTypeParameterConstraintVisibilityError;
245    }
246    else if (isExpressionWithTypeArguments(node)) {
247        return getHeritageClauseVisibilityError;
248    }
249    else if (isImportEqualsDeclaration(node)) {
250        return getImportEntityNameVisibilityError;
251    }
252    else if (isTypeAliasDeclaration(node) || isJSDocTypeAlias(node)) {
253        return getTypeAliasDeclarationVisibilityError;
254    }
255    else {
256        return Debug.assertNever(node, `Attempted to set a declaration diagnostic context for unhandled node kind: ${Debug.formatSyntaxKind((node as Node).kind)}`);
257    }
258
259    function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) {
260        if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) {
261            return symbolAccessibilityResult.errorModuleName ?
262                symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
263                    Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
264                    Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
265                Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
266        }
267        // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
268        // The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all.
269        else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertyAccessExpression || node.kind === SyntaxKind.PropertySignature ||
270            (node.kind === SyntaxKind.Parameter && hasSyntacticModifier(node.parent, ModifierFlags.Private))) {
271            // TODO(jfreeman): Deal with computed properties in error reporting.
272            if (isStatic(node)) {
273                return symbolAccessibilityResult.errorModuleName ?
274                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
275                        Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
276                        Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
277                    Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
278            }
279            else if (node.parent.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.Parameter) {
280                return symbolAccessibilityResult.errorModuleName ?
281                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
282                        Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
283                        Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
284                    Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
285            }
286            else {
287                // Interfaces cannot have types that cannot be named
288                return symbolAccessibilityResult.errorModuleName ?
289                    Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
290                    Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
291            }
292        }
293    }
294
295    function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined {
296        const diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
297        return diagnosticMessage !== undefined ? {
298            diagnosticMessage,
299            errorNode: node,
300            typeName: (node as NamedDeclaration).name
301        } : undefined;
302    }
303
304    function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
305        let diagnosticMessage: DiagnosticMessage;
306        if (node.kind === SyntaxKind.SetAccessor) {
307            // Getters can infer the return type from the returned expression, but setters cannot, so the
308            // "_from_external_module_1_but_cannot_be_named" case cannot occur.
309            if (isStatic(node)) {
310                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
311                    Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
312                    Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1;
313            }
314            else {
315                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
316                    Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
317                    Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1;
318            }
319        }
320        else {
321            if (isStatic(node)) {
322                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
323                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
324                        Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
325                        Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
326                    Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1;
327            }
328            else {
329                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
330                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
331                        Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
332                        Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
333                    Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1;
334            }
335        }
336        return {
337            diagnosticMessage,
338            errorNode: (node as NamedDeclaration).name!,
339            typeName: (node as NamedDeclaration).name
340        };
341    }
342
343    function getReturnTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
344        let diagnosticMessage: DiagnosticMessage;
345        switch (node.kind) {
346            case SyntaxKind.ConstructSignature:
347                // Interfaces cannot have return types that cannot be named
348                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
349                    Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
350                    Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
351                break;
352
353            case SyntaxKind.CallSignature:
354                // Interfaces cannot have return types that cannot be named
355                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
356                    Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
357                    Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
358                break;
359
360            case SyntaxKind.IndexSignature:
361                // Interfaces cannot have return types that cannot be named
362                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
363                    Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
364                    Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
365                break;
366
367            case SyntaxKind.MethodDeclaration:
368            case SyntaxKind.MethodSignature:
369                if (isStatic(node)) {
370                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
371                        symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
372                            Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
373                            Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
374                        Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
375                }
376                else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
377                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
378                        symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
379                            Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
380                            Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
381                        Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
382                }
383                else {
384                    // Interfaces cannot have return types that cannot be named
385                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
386                        Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
387                        Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
388                }
389                break;
390
391            case SyntaxKind.FunctionDeclaration:
392                diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
393                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
394                        Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
395                        Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 :
396                    Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
397                break;
398
399            default:
400                return Debug.fail("This is unknown kind for signature: " + node.kind);
401        }
402
403        return {
404            diagnosticMessage,
405            errorNode: (node as NamedDeclaration).name || node
406        };
407    }
408
409    function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined {
410        const diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
411        return diagnosticMessage !== undefined ? {
412            diagnosticMessage,
413            errorNode: node,
414            typeName: (node as NamedDeclaration).name
415        } : undefined;
416    }
417
418    function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult): DiagnosticMessage {
419        switch (node.parent.kind) {
420            case SyntaxKind.Constructor:
421                return symbolAccessibilityResult.errorModuleName ?
422                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
423                        Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
424                        Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
425                    Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
426
427            case SyntaxKind.ConstructSignature:
428            case SyntaxKind.ConstructorType:
429                // Interfaces cannot have parameter types that cannot be named
430                return symbolAccessibilityResult.errorModuleName ?
431                    Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
432                    Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
433
434            case SyntaxKind.CallSignature:
435                // Interfaces cannot have parameter types that cannot be named
436                return symbolAccessibilityResult.errorModuleName ?
437                    Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
438                    Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
439
440            case SyntaxKind.IndexSignature:
441                // Interfaces cannot have parameter types that cannot be named
442                return symbolAccessibilityResult.errorModuleName ?
443                    Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
444                    Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
445
446            case SyntaxKind.MethodDeclaration:
447            case SyntaxKind.MethodSignature:
448                if (isStatic(node.parent)) {
449                    return symbolAccessibilityResult.errorModuleName ?
450                        symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
451                            Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
452                            Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
453                        Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
454                }
455                else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
456                    return symbolAccessibilityResult.errorModuleName ?
457                        symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
458                            Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
459                            Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
460                        Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
461                }
462                else {
463                    // Interfaces cannot have parameter types that cannot be named
464                    return symbolAccessibilityResult.errorModuleName ?
465                        Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
466                        Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
467                }
468
469            case SyntaxKind.FunctionDeclaration:
470            case SyntaxKind.FunctionType:
471                return symbolAccessibilityResult.errorModuleName ?
472                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
473                        Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
474                        Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
475                    Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
476            case SyntaxKind.SetAccessor:
477            case SyntaxKind.GetAccessor:
478                return symbolAccessibilityResult.errorModuleName ?
479                    symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ?
480                        Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
481                        Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2 :
482                    Diagnostics.Parameter_0_of_accessor_has_or_is_using_private_name_1;
483
484            default:
485                return Debug.fail(`Unknown parent for parameter: ${Debug.formatSyntaxKind(node.parent.kind)}`);
486        }
487    }
488
489    function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic {
490        // Type parameter constraints are named by user so we should always be able to name it
491        let diagnosticMessage: DiagnosticMessage;
492        switch (node.parent.kind) {
493            case SyntaxKind.ClassDeclaration:
494                diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
495                break;
496
497            case SyntaxKind.InterfaceDeclaration:
498                diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
499                break;
500
501            case SyntaxKind.MappedType:
502                diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1;
503                break;
504
505            case SyntaxKind.ConstructorType:
506            case SyntaxKind.ConstructSignature:
507                diagnosticMessage = Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
508                break;
509
510            case SyntaxKind.CallSignature:
511                diagnosticMessage = Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
512                break;
513
514            case SyntaxKind.MethodDeclaration:
515            case SyntaxKind.MethodSignature:
516                if (isStatic(node.parent)) {
517                    diagnosticMessage = Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
518                }
519                else if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
520                    diagnosticMessage = Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
521                }
522                else {
523                    diagnosticMessage = Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
524                }
525                break;
526
527            case SyntaxKind.FunctionType:
528            case SyntaxKind.FunctionDeclaration:
529                diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
530                break;
531
532            case SyntaxKind.TypeAliasDeclaration:
533                diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1;
534                break;
535
536            default:
537                return Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
538        }
539
540        return {
541            diagnosticMessage,
542            errorNode: node,
543            typeName: (node as NamedDeclaration).name
544        };
545    }
546
547    function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic {
548        let diagnosticMessage: DiagnosticMessage;
549        // Heritage clause is written by user so it can always be named
550        if (isClassDeclaration(node.parent.parent)) {
551            // Class or Interface implemented/extended is inaccessible
552            diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === SyntaxKind.ImplementsKeyword ?
553                Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
554                    node.parent.parent.name ? Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1 :
555                        Diagnostics.extends_clause_of_exported_class_has_or_is_using_private_name_0;
556        }
557        else {
558            // interface is inaccessible
559            diagnosticMessage = Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
560        }
561
562        return {
563            diagnosticMessage,
564            errorNode: node,
565            typeName: getNameOfDeclaration(node.parent.parent as Declaration)
566        };
567    }
568
569    function getImportEntityNameVisibilityError(): SymbolAccessibilityDiagnostic {
570        return {
571            diagnosticMessage: Diagnostics.Import_declaration_0_is_using_private_name_1,
572            errorNode: node,
573            typeName: (node as NamedDeclaration).name
574        };
575    }
576
577    function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
578        return {
579            diagnosticMessage: symbolAccessibilityResult.errorModuleName
580                ? Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1_from_module_2
581                : Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
582            errorNode: isJSDocTypeAlias(node) ? Debug.checkDefined(node.typeExpression) : (node as TypeAliasDeclaration).type,
583            typeName: isJSDocTypeAlias(node) ? getNameOfDeclaration(node) : (node as TypeAliasDeclaration).name,
584        };
585    }
586}
587
588/** @internal */
589export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
590    const relatedSuggestionByDeclarationKind = {
591        [SyntaxKind.ArrowFunction]: Diagnostics.Add_a_return_type_to_the_function_expression,
592        [SyntaxKind.FunctionExpression]: Diagnostics.Add_a_return_type_to_the_function_expression,
593        [SyntaxKind.MethodDeclaration]: Diagnostics.Add_a_return_type_to_the_method,
594        [SyntaxKind.GetAccessor]: Diagnostics.Add_a_return_type_to_the_get_accessor_declaration,
595        [SyntaxKind.SetAccessor]: Diagnostics.Add_a_type_to_parameter_of_the_set_accessor_declaration,
596        [SyntaxKind.FunctionDeclaration]: Diagnostics.Add_a_return_type_to_the_function_declaration,
597        [SyntaxKind.ConstructSignature]: Diagnostics.Add_a_return_type_to_the_function_declaration,
598        [SyntaxKind.Parameter]: Diagnostics.Add_a_type_annotation_to_the_parameter_0,
599        [SyntaxKind.VariableDeclaration]: Diagnostics.Add_a_type_annotation_to_the_variable_0,
600        [SyntaxKind.PropertyDeclaration]: Diagnostics.Add_a_type_annotation_to_the_property_0,
601        [SyntaxKind.PropertySignature]: Diagnostics.Add_a_type_annotation_to_the_property_0,
602        [SyntaxKind.ExportAssignment]: Diagnostics.Move_the_expression_in_default_export_to_a_variable_and_add_a_type_annotation_to_it,
603    } satisfies Partial<Record<SyntaxKind, DiagnosticMessage>>;
604
605    const errorByDeclarationKind = {
606        [SyntaxKind.FunctionExpression]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
607        [SyntaxKind.FunctionDeclaration]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
608        [SyntaxKind.ArrowFunction]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
609        [SyntaxKind.MethodDeclaration]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
610        [SyntaxKind.ConstructSignature]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
611        [SyntaxKind.GetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
612        [SyntaxKind.SetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
613        [SyntaxKind.Parameter]: Diagnostics.Parameter_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
614        [SyntaxKind.VariableDeclaration]: Diagnostics.Variable_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
615        [SyntaxKind.PropertyDeclaration]: Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
616        [SyntaxKind.PropertySignature]: Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
617        [SyntaxKind.ComputedPropertyName]: Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations,
618        [SyntaxKind.SpreadAssignment]: Diagnostics.Objects_that_contain_spread_assignments_can_t_be_inferred_with_isolatedDeclarations,
619        [SyntaxKind.ShorthandPropertyAssignment]: Diagnostics.Objects_that_contain_shorthand_properties_can_t_be_inferred_with_isolatedDeclarations,
620        [SyntaxKind.ArrayLiteralExpression]: Diagnostics.Only_const_arrays_can_be_inferred_with_isolatedDeclarations,
621        [SyntaxKind.ExportAssignment]: Diagnostics.Default_exports_can_t_be_inferred_with_isolatedDeclarations,
622        [SyntaxKind.SpreadElement]: Diagnostics.Arrays_with_spread_elements_can_t_inferred_with_isolatedDeclarations,
623    } satisfies Partial<Record<SyntaxKind, DiagnosticMessage>>;
624
625    return getDiagnostic;
626
627    type WithIsolatedDeclarationDiagnostic =
628        | GetAccessorDeclaration
629        | SetAccessorDeclaration
630        | ShorthandPropertyAssignment
631        | SpreadAssignment
632        | ComputedPropertyName
633        | ArrayLiteralExpression
634        | SpreadElement
635        | FunctionDeclaration
636        | FunctionExpression
637        | ArrowFunction
638        | MethodDeclaration
639        | ConstructSignatureDeclaration
640        | BindingElement
641        | VariableDeclaration
642        | PropertyDeclaration
643        | ParameterDeclaration
644        | PropertyAssignment
645        | ClassExpression;
646
647    function getDiagnostic(node: Node) {
648        const heritageClause = findAncestor(node, isHeritageClause);
649        if (heritageClause) {
650            return createDiagnosticForNode(node, Diagnostics.Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations);
651        }
652        Debug.type<WithIsolatedDeclarationDiagnostic>(node);
653        switch (node.kind) {
654            case SyntaxKind.GetAccessor:
655            case SyntaxKind.SetAccessor:
656                return createAccessorTypeError(node);
657            case SyntaxKind.ComputedPropertyName:
658            case SyntaxKind.ShorthandPropertyAssignment:
659            case SyntaxKind.SpreadAssignment:
660                return createObjectLiteralError(node);
661            case SyntaxKind.ArrayLiteralExpression:
662            case SyntaxKind.SpreadElement:
663                return createArrayLiteralError(node);
664            case SyntaxKind.MethodDeclaration:
665            case SyntaxKind.ConstructSignature:
666            case SyntaxKind.FunctionExpression:
667            case SyntaxKind.ArrowFunction:
668            case SyntaxKind.FunctionDeclaration:
669                return createReturnTypeError(node);
670            case SyntaxKind.BindingElement:
671                return createBindingElementError(node);
672            case SyntaxKind.PropertyDeclaration:
673            case SyntaxKind.VariableDeclaration:
674                return createVariableOrPropertyError(node);
675            case SyntaxKind.Parameter:
676                return createParameterError(node);
677            case SyntaxKind.PropertyAssignment:
678                return createExpressionError(node.initializer);
679            case SyntaxKind.ClassExpression:
680                return createClassExpressionError(node);
681            default:
682                assertType<never>(node);
683                return createExpressionError(node as Expression);
684        }
685    }
686
687    function findNearestDeclaration(node: Node) {
688        const result = findAncestor(node, n => isExportAssignment(n) || (isStatement(n) ? "quit" : isVariableDeclaration(n) || isPropertyDeclaration(n) || isParameter(n)));
689        return result as VariableDeclaration | PropertyDeclaration | ParameterDeclaration | ExportAssignment | undefined;
690    }
691
692    function createAccessorTypeError(node: GetAccessorDeclaration | SetAccessorDeclaration) {
693        const { getAccessor, setAccessor } = getAllAccessorDeclarations(node.symbol.declarations, node);
694
695        const targetNode = (isSetAccessor(node) ? node.parameters[0] : node) ?? node;
696        const diag = createDiagnosticForNode(targetNode, errorByDeclarationKind[node.kind]);
697
698        if (setAccessor) {
699            addRelatedInfo(diag, createDiagnosticForNode(setAccessor, relatedSuggestionByDeclarationKind[setAccessor.kind]));
700        }
701        if (getAccessor) {
702            addRelatedInfo(diag, createDiagnosticForNode(getAccessor, relatedSuggestionByDeclarationKind[getAccessor.kind]));
703        }
704        return diag;
705    }
706    function createObjectLiteralError(node: ShorthandPropertyAssignment | SpreadAssignment | ComputedPropertyName) {
707        const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
708        const parentDeclaration = findNearestDeclaration(node);
709        if (parentDeclaration) {
710            const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
711            addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
712        }
713        return diag;
714    }
715    function createArrayLiteralError(node: ArrayLiteralExpression | SpreadElement) {
716        const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
717        const parentDeclaration = findNearestDeclaration(node);
718        if (parentDeclaration) {
719            const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
720            addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
721        }
722        return diag;
723    }
724    function createReturnTypeError(node: FunctionDeclaration | FunctionExpression | ArrowFunction | MethodDeclaration | ConstructSignatureDeclaration) {
725        const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
726        const parentDeclaration = findNearestDeclaration(node);
727        if (parentDeclaration) {
728            const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
729            addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
730        }
731        addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind]));
732        return diag;
733    }
734    function createBindingElementError(node: BindingElement) {
735        return createDiagnosticForNode(node, Diagnostics.Binding_elements_can_t_be_exported_directly_with_isolatedDeclarations);
736    }
737    function createVariableOrPropertyError(node: VariableDeclaration | PropertyDeclaration) {
738        const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
739        const targetStr = getTextOfNode(node.name, /*includeTrivia*/ false);
740        addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind], targetStr));
741        return diag;
742    }
743    function createParameterError(node: ParameterDeclaration) {
744        if (isSetAccessor(node.parent)) {
745            return createAccessorTypeError(node.parent);
746        }
747        const addUndefined = resolver.requiresAddingImplicitUndefined(node);
748        if (!addUndefined && node.initializer) {
749            return createExpressionError(node.initializer);
750        }
751        const message = addUndefined ?
752            Diagnostics.Declaration_emit_for_this_parameter_requires_implicitly_adding_undefined_to_it_s_type_This_is_not_supported_with_isolatedDeclarations :
753            errorByDeclarationKind[node.kind];
754        const diag = createDiagnosticForNode(node, message);
755        const targetStr = getTextOfNode(node.name, /*includeTrivia*/ false);
756        addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind], targetStr));
757        return diag;
758    }
759    function createClassExpressionError(node: Expression) {
760        return createExpressionError(node, Diagnostics.Inference_from_class_expressions_is_not_supported_with_isolatedDeclarations);
761    }
762    function createExpressionError(node: Expression, diagnosticMessage?: DiagnosticMessage) {
763        const parentDeclaration = findNearestDeclaration(node);
764        let diag: DiagnosticWithLocation;
765        if (parentDeclaration) {
766            const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
767            const parent = findAncestor(node.parent, n => isExportAssignment(n) || (isStatement(n) ? "quit" : !isParenthesizedExpression(n) && !isTypeAssertionExpression(n) && !isAsExpression(n)));
768            if (parentDeclaration === parent) {
769                diag = createDiagnosticForNode(node, diagnosticMessage ?? errorByDeclarationKind[parentDeclaration.kind]);
770                addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
771            }
772            else {
773                diag = createDiagnosticForNode(node, diagnosticMessage ?? Diagnostics.Expression_type_can_t_be_inferred_with_isolatedDeclarations);
774                addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
775                addRelatedInfo(diag, createDiagnosticForNode(node, Diagnostics.Add_satisfies_and_a_type_assertion_to_this_expression_satisfies_T_as_T_to_make_the_type_explicit));
776            }
777        }
778        else {
779            diag = createDiagnosticForNode(node, diagnosticMessage ?? Diagnostics.Expression_type_can_t_be_inferred_with_isolatedDeclarations);
780        }
781        return diag;
782    }
783}