Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not remove binding alias in function declarations #57020

Merged
merged 1 commit into from Jan 12, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/compiler/checker.ts
Expand Up @@ -6225,16 +6225,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

function hasVisibleDeclarations(symbol: Symbol, shouldComputeAliasToMakeVisible: boolean): SymbolVisibilityResult | undefined {
let aliasesToMakeVisible: LateVisibilityPaintedStatement[] | undefined;
let bindingElementToMakeVisible: BindingElement | undefined;
if (!every(filter(symbol.declarations, d => d.kind !== SyntaxKind.Identifier), getIsDeclarationVisible)) {
return undefined;
}
return { accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible, bindingElementToMakeVisible };
return { accessibility: SymbolAccessibility.Accessible, aliasesToMakeVisible };

function getIsDeclarationVisible(declaration: Declaration) {
if (isBindingElement(declaration) && findAncestor(declaration, isParameter)) {
bindingElementToMakeVisible = declaration;
}
if (!isDeclarationVisible(declaration)) {
// Mark the unexported alias as visible if its parent is visible
// because these kind of aliases can be used to name types in declaration file
Expand Down
340 changes: 57 additions & 283 deletions src/compiler/transformers/declarations.ts

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion src/compiler/types.ts
Expand Up @@ -5592,7 +5592,6 @@ export type LateVisibilityPaintedStatement =
/** @internal */
export interface SymbolVisibilityResult {
accessibility: SymbolAccessibility;
bindingElementToMakeVisible?: BindingElement;
aliasesToMakeVisible?: LateVisibilityPaintedStatement[]; // aliases that need to have this symbol visible
errorSymbolName?: string; // Optional symbol name that results in error
errorNode?: Node; // optional node that results in error
Expand Down
@@ -0,0 +1,43 @@
//// [tests/cases/compiler/declarationEmitBindingPatternsFunctionExpr.ts] ////

//// [declarationEmitBindingPatternsFunctionExpr.ts]
type Named = { name: string }
// Tempting to remove alias if unused
let notReferenced = ({ name: alias }: Named) => { }

// Resons we can't remove aliases that are not used in the function signature:

// 1.Causes duplicate identifier if we remove alias
const duplicateIndetifiers = ({ name: alias, name: alias2 }: Named) => { }
const duplicateIndetifiers2 = (name: string, { name: alias }: Named) => { }
const duplicateIndetifiers3 = ({ name: alias }: Named, { name: alias2 }: Named) => { }

let value = "";
// 2.Can change in meaning for typeof value if we remove alias
const shadowedVariable = ({ value: alias }: { value: string }): typeof value => value;

//// [declarationEmitBindingPatternsFunctionExpr.js]
// Tempting to remove alias if unused
let notReferenced = ({ name: alias }) => { };
// Resons we can't remove aliases that are not used in the function signature:
// 1.Causes duplicate identifier if we remove alias
const duplicateIndetifiers = ({ name: alias, name: alias2 }) => { };
const duplicateIndetifiers2 = (name, { name: alias }) => { };
const duplicateIndetifiers3 = ({ name: alias }, { name: alias2 }) => { };
let value = "";
// 2.Can change in meaning for typeof value if we remove alias
const shadowedVariable = ({ value: alias }) => value;


//// [declarationEmitBindingPatternsFunctionExpr.d.ts]
type Named = {
name: string;
};
declare let notReferenced: ({ name: alias }: Named) => void;
declare const duplicateIndetifiers: ({ name: alias, name: alias2 }: Named) => void;
declare const duplicateIndetifiers2: (name: string, { name: alias }: Named) => void;
declare const duplicateIndetifiers3: ({ name: alias }: Named, { name: alias2 }: Named) => void;
declare let value: string;
declare const shadowedVariable: ({ value: alias }: {
value: string;
}) => typeof value;
@@ -0,0 +1,53 @@
//// [tests/cases/compiler/declarationEmitBindingPatternsFunctionExpr.ts] ////

=== declarationEmitBindingPatternsFunctionExpr.ts ===
type Named = { name: string }
>Named : Symbol(Named, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 0))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 14))

// Tempting to remove alias if unused
let notReferenced = ({ name: alias }: Named) => { }
>notReferenced : Symbol(notReferenced, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 2, 3))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 14))
>alias : Symbol(alias, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 2, 22))
>Named : Symbol(Named, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 0))

// Resons we can't remove aliases that are not used in the function signature:

// 1.Causes duplicate identifier if we remove alias
const duplicateIndetifiers = ({ name: alias, name: alias2 }: Named) => { }
>duplicateIndetifiers : Symbol(duplicateIndetifiers, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 7, 5))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 14))
>alias : Symbol(alias, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 7, 31))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 14))
>alias2 : Symbol(alias2, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 7, 44))
>Named : Symbol(Named, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 0))

const duplicateIndetifiers2 = (name: string, { name: alias }: Named) => { }
>duplicateIndetifiers2 : Symbol(duplicateIndetifiers2, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 8, 5))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 8, 31))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 14))
>alias : Symbol(alias, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 8, 46))
>Named : Symbol(Named, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 0))

const duplicateIndetifiers3 = ({ name: alias }: Named, { name: alias2 }: Named) => { }
>duplicateIndetifiers3 : Symbol(duplicateIndetifiers3, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 9, 5))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 14))
>alias : Symbol(alias, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 9, 32))
>Named : Symbol(Named, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 0))
>name : Symbol(name, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 14))
>alias2 : Symbol(alias2, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 9, 56))
>Named : Symbol(Named, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 0, 0))

let value = "";
>value : Symbol(value, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 11, 3))

// 2.Can change in meaning for typeof value if we remove alias
const shadowedVariable = ({ value: alias }: { value: string }): typeof value => value;
>shadowedVariable : Symbol(shadowedVariable, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 13, 5))
>value : Symbol(value, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 13, 45))
>alias : Symbol(alias, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 13, 27))
>value : Symbol(value, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 13, 45))
>value : Symbol(value, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 11, 3))
>value : Symbol(value, Decl(declarationEmitBindingPatternsFunctionExpr.ts, 11, 3))

@@ -0,0 +1,54 @@
//// [tests/cases/compiler/declarationEmitBindingPatternsFunctionExpr.ts] ////

=== declarationEmitBindingPatternsFunctionExpr.ts ===
type Named = { name: string }
>Named : { name: string; }
>name : string

// Tempting to remove alias if unused
let notReferenced = ({ name: alias }: Named) => { }
>notReferenced : ({ name: alias }: Named) => void
>({ name: alias }: Named) => { } : ({ name: alias }: Named) => void
>name : any
>alias : string

// Resons we can't remove aliases that are not used in the function signature:

// 1.Causes duplicate identifier if we remove alias
const duplicateIndetifiers = ({ name: alias, name: alias2 }: Named) => { }
>duplicateIndetifiers : ({ name: alias, name: alias2 }: Named) => void
>({ name: alias, name: alias2 }: Named) => { } : ({ name: alias, name: alias2 }: Named) => void
>name : any
>alias : string
>name : any
>alias2 : string

const duplicateIndetifiers2 = (name: string, { name: alias }: Named) => { }
>duplicateIndetifiers2 : (name: string, { name: alias }: Named) => void
>(name: string, { name: alias }: Named) => { } : (name: string, { name: alias }: Named) => void
>name : string
>name : any
>alias : string

const duplicateIndetifiers3 = ({ name: alias }: Named, { name: alias2 }: Named) => { }
>duplicateIndetifiers3 : ({ name: alias }: Named, { name: alias2 }: Named) => void
>({ name: alias }: Named, { name: alias2 }: Named) => { } : ({ name: alias }: Named, { name: alias2 }: Named) => void
>name : any
>alias : string
>name : any
>alias2 : string

let value = "";
>value : string
>"" : ""

// 2.Can change in meaning for typeof value if we remove alias
const shadowedVariable = ({ value: alias }: { value: string }): typeof value => value;
>shadowedVariable : ({ value: alias }: { value: string;}) => typeof value
>({ value: alias }: { value: string }): typeof value => value : ({ value: alias }: { value: string;}) => typeof value
>value : any
>alias : string
>value : string
>value : string
>value : string

@@ -1,13 +1,25 @@
declarationEmitBindingPatternsUnused.ts(85,35): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(89,41): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(95,11): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(96,15): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(97,16): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(98,12): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(95,35): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(99,41): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(105,11): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(106,15): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(107,16): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?
declarationEmitBindingPatternsUnused.ts(108,12): error TS2842: 'alias' is an unused renaming of 'name'. Did you intend to use it as a type annotation?


==== declarationEmitBindingPatternsUnused.ts (6 errors) ====
type Named = { name: string }

// Resons we can't remove aliases that are not used in the function signature:

// 1.Causes duplicate identifier if we remove alias
function duplicateIndetifiers({ name: alias, name: alias2 }: Named) { }
function duplicateIndetifiers2(name: string, { name: alias }: Named) { }
function duplicateIndetifiers3({ name: alias }: Named, { name: alias2 }: Named) { }

let value = "";
// 2.Can change in meaning for typeof value if we remove alias
function shadowedVariable({ value: alias }: { value: string }): typeof value { return value }

function notReferenced({ name: alias }: Named) {

}
Expand All @@ -16,8 +28,6 @@ declarationEmitBindingPatternsUnused.ts(98,12): error TS2842: 'alias' is an unus
function notReferencedArrayAlias([a, b, { name: alias }]: Named[]) {
}



function referencedInCode({ name: alias }: Named) {
return alias;
}
Expand Down
61 changes: 43 additions & 18 deletions tests/baselines/reference/declarationEmitBindingPatternsUnused.js
Expand Up @@ -2,6 +2,18 @@

//// [declarationEmitBindingPatternsUnused.ts]
type Named = { name: string }

// Resons we can't remove aliases that are not used in the function signature:

// 1.Causes duplicate identifier if we remove alias
function duplicateIndetifiers({ name: alias, name: alias2 }: Named) { }
function duplicateIndetifiers2(name: string, { name: alias }: Named) { }
function duplicateIndetifiers3({ name: alias }: Named, { name: alias2 }: Named) { }

let value = "";
// 2.Can change in meaning for typeof value if we remove alias
function shadowedVariable({ value: alias }: { value: string }): typeof value { return value }

function notReferenced({ name: alias }: Named) {

}
Expand All @@ -10,8 +22,6 @@ function notReferencedNestedAlias({ p: { name: alias } }: { p: Named }) {
function notReferencedArrayAlias([a, b, { name: alias }]: Named[]) {
}



function referencedInCode({ name: alias }: Named) {
return alias;
}
Expand Down Expand Up @@ -114,6 +124,14 @@ interface ReferencedInSignartureInterface {
}

//// [declarationEmitBindingPatternsUnused.js]
// Resons we can't remove aliases that are not used in the function signature:
// 1.Causes duplicate identifier if we remove alias
function duplicateIndetifiers({ name: alias, name: alias2 }) { }
function duplicateIndetifiers2(name, { name: alias }) { }
function duplicateIndetifiers3({ name: alias }, { name: alias2 }) { }
let value = "";
// 2.Can change in meaning for typeof value if we remove alias
function shadowedVariable({ value: alias }) { return value; }
function notReferenced({ name: alias }) {
}
function notReferencedNestedAlias({ p: { name: alias } }) {
Expand Down Expand Up @@ -191,12 +209,19 @@ let referencedInSignartureParamTypeCtorType;
type Named = {
name: string;
};
declare function notReferenced({ name }: Named): void;
declare function notReferencedNestedAlias({ p: { name } }: {
declare function duplicateIndetifiers({ name: alias, name: alias2 }: Named): void;
declare function duplicateIndetifiers2(name: string, { name: alias }: Named): void;
declare function duplicateIndetifiers3({ name: alias }: Named, { name: alias2 }: Named): void;
declare let value: string;
declare function shadowedVariable({ value: alias }: {
value: string;
}): typeof value;
declare function notReferenced({ name: alias }: Named): void;
declare function notReferencedNestedAlias({ p: { name: alias } }: {
p: Named;
}): void;
declare function notReferencedArrayAlias([a, b, { name }]: Named[]): void;
declare function referencedInCode({ name }: Named): string;
declare function notReferencedArrayAlias([a, b, { name: alias }]: Named[]): void;
declare function referencedInCode({ name: alias }: Named): string;
declare function referencedInSignarture({ name: alias }: Named): typeof alias;
declare function referencedInSignartureKeyword({ function: alias }: {
function: string;
Expand All @@ -210,14 +235,14 @@ declare function referencedNestedAlias({ p: { name: alias } }: {
}): typeof alias;
declare function referencedArrayAlias([a, b, { name: alias }]: Named[]): typeof alias;
declare class NotReferencedClass {
constructor({ name }: Named);
set x({ name }: Named);
m({ name }: Named): void;
constructor({ name: alias }: Named);
set x({ name: alias }: Named);
m({ name: alias }: Named): void;
}
declare class ReferencedInCodeClas {
constructor({ name }: Named);
set x({ name }: Named);
m({ name }: Named): void;
constructor({ name: alias }: Named);
set x({ name: alias }: Named);
m({ name: alias }: Named): void;
}
declare class ReferencedInSignartureClass {
constructor({ name: alias }: Named, p: typeof alias);
Expand All @@ -228,17 +253,17 @@ declare class ReferencedInSignartureClass {
mRerturnTypeNested({ name: alias }: Named): NonNullable<typeof alias>;
mParameter({ name: alias }: Named, p: typeof alias): any;
}
declare let notReferencedFnType: ({ name }: Named) => void;
declare let notReferencedFnType: ({ name: alias }: Named) => void;
declare let referencedInSignartureReturnTypeFnType: ({ name: alias }: Named) => typeof alias;
declare let referencedInSignartureParamTypeFnType: ({ name: alias }: Named, p: typeof alias) => void;
declare let notReferencedCtorType: new ({ name }: Named) => void;
declare let notReferencedCtorType: new ({ name: alias }: Named) => void;
declare let referencedInSignartureReturnTypeCtorType: new ({ name: alias }: Named) => typeof alias;
declare let referencedInSignartureParamTypeCtorType: new ({ name: alias }: Named, p: typeof alias) => void;
interface NotReferencedInterface {
({ name }: Named): void;
new ({ name }: Named): void;
set x({ name }: Named);
m({ name }: Named): any;
({ name: alias }: Named): void;
new ({ name: alias }: Named): void;
set x({ name: alias }: Named);
m({ name: alias }: Named): any;
}
interface ReferencedInSignartureInterface {
({ name: alias }: Named, p: typeof alias): void;
Expand Down