Skip to content

Commit

Permalink
Do not remove binding alias in function declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
dragomirtitian committed Jan 12, 2024
1 parent 7f3e34b commit bdabd74
Show file tree
Hide file tree
Showing 16 changed files with 525 additions and 472 deletions.
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

0 comments on commit bdabd74

Please sign in to comment.