Skip to content

Commit 599d2b0

Browse files
authored
Merge pull request microsoft#10953 from Microsoft/emitTypeAliasInDeclarationFile
Serialize inferred type alias when type alias symbol is not accessible
2 parents 949c197 + 94cd9ae commit 599d2b0

File tree

151 files changed

+1493
-746
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+1493
-746
lines changed

src/compiler/checker.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,15 +1758,23 @@ namespace ts {
17581758
return false;
17591759
}
17601760

1761-
function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult {
1761+
/**
1762+
* Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested
1763+
*
1764+
* @param symbol a Symbol to check if accessible
1765+
* @param enclosingDeclaration a Node containing reference to the symbol
1766+
* @param meaning a SymbolFlags to check if such meaning of the symbol is accessible
1767+
* @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
1768+
*/
1769+
function isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasesToMakeVisible: boolean): SymbolAccessibilityResult {
17621770
if (symbol && enclosingDeclaration && !(symbol.flags & SymbolFlags.TypeParameter)) {
17631771
const initialSymbol = symbol;
17641772
let meaningToLook = meaning;
17651773
while (symbol) {
17661774
// Symbol is accessible if it by itself is accessible
17671775
const accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaningToLook, /*useOnlyExternalAliasing*/ false);
17681776
if (accessibleSymbolChain) {
1769-
const hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0]);
1777+
const hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible);
17701778
if (!hasAccessibleDeclarations) {
17711779
return <SymbolAccessibilityResult>{
17721780
accessibility: SymbolAccessibility.NotAccessible,
@@ -1830,7 +1838,7 @@ namespace ts {
18301838
return isAmbientModule(declaration) || (declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(<SourceFile>declaration));
18311839
}
18321840

1833-
function hasVisibleDeclarations(symbol: Symbol): SymbolVisibilityResult {
1841+
function hasVisibleDeclarations(symbol: Symbol, shouldComputeAliasToMakeVisible: boolean): SymbolVisibilityResult {
18341842
let aliasesToMakeVisible: AnyImportSyntax[];
18351843
if (forEach(symbol.declarations, declaration => !getIsDeclarationVisible(declaration))) {
18361844
return undefined;
@@ -1846,14 +1854,19 @@ namespace ts {
18461854
if (anyImportSyntax &&
18471855
!(getModifierFlags(anyImportSyntax) & ModifierFlags.Export) && // import clause without export
18481856
isDeclarationVisible(<Declaration>anyImportSyntax.parent)) {
1849-
getNodeLinks(declaration).isVisible = true;
1850-
if (aliasesToMakeVisible) {
1851-
if (!contains(aliasesToMakeVisible, anyImportSyntax)) {
1852-
aliasesToMakeVisible.push(anyImportSyntax);
1857+
// In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types,
1858+
// we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time
1859+
// since we will do the emitting later in trackSymbol.
1860+
if (shouldComputeAliasToMakeVisible) {
1861+
getNodeLinks(declaration).isVisible = true;
1862+
if (aliasesToMakeVisible) {
1863+
if (!contains(aliasesToMakeVisible, anyImportSyntax)) {
1864+
aliasesToMakeVisible.push(anyImportSyntax);
1865+
}
1866+
}
1867+
else {
1868+
aliasesToMakeVisible = [anyImportSyntax];
18531869
}
1854-
}
1855-
else {
1856-
aliasesToMakeVisible = [anyImportSyntax];
18571870
}
18581871
return true;
18591872
}
@@ -1888,7 +1901,7 @@ namespace ts {
18881901
const symbol = resolveName(enclosingDeclaration, (<Identifier>firstIdentifier).text, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined);
18891902

18901903
// Verify if the symbol is accessible
1891-
return (symbol && hasVisibleDeclarations(symbol)) || <SymbolVisibilityResult>{
1904+
return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || <SymbolVisibilityResult>{
18921905
accessibility: SymbolAccessibility.NotAccessible,
18931906
errorSymbolName: getTextOfNode(firstIdentifier),
18941907
errorNode: firstIdentifier
@@ -2163,7 +2176,9 @@ namespace ts {
21632176
// The specified symbol flags need to be reinterpreted as type flags
21642177
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
21652178
}
2166-
else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol) {
2179+
else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
2180+
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
2181+
// Only write out inferred type with its corresponding type-alias if type-alias is visible
21672182
const typeArguments = type.aliasTypeArguments;
21682183
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
21692184
}

src/compiler/declarationEmitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ namespace ts {
306306
}
307307

308308
function trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags) {
309-
handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning));
309+
handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
310310
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
311311
}
312312

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2144,7 +2144,7 @@ namespace ts {
21442144
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
21452145
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
21462146
writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
2147-
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessibilityResult;
2147+
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
21482148
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult;
21492149
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
21502150
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;

tests/baselines/reference/controlFlowBinaryOrExpression.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,21 @@ declare function isHTMLCollection(sourceObj: any): sourceObj is HTMLCollection;
6262
>HTMLCollection : HTMLCollection
6363

6464
type EventTargetLike = {a: string} | HTMLCollection | NodeList;
65-
>EventTargetLike : EventTargetLike
65+
>EventTargetLike : NodeList | HTMLCollection | { a: string; }
6666
>a : string
6767
>HTMLCollection : HTMLCollection
6868
>NodeList : NodeList
6969

7070
var sourceObj: EventTargetLike = <any>undefined;
71-
>sourceObj : EventTargetLike
72-
>EventTargetLike : EventTargetLike
71+
>sourceObj : NodeList | HTMLCollection | { a: string; }
72+
>EventTargetLike : NodeList | HTMLCollection | { a: string; }
7373
><any>undefined : any
7474
>undefined : undefined
7575

7676
if (isNodeList(sourceObj)) {
7777
>isNodeList(sourceObj) : boolean
7878
>isNodeList : (sourceObj: any) => sourceObj is NodeList
79-
>sourceObj : EventTargetLike
79+
>sourceObj : NodeList | HTMLCollection | { a: string; }
8080

8181
sourceObj.length;
8282
>sourceObj.length : number
@@ -87,7 +87,7 @@ if (isNodeList(sourceObj)) {
8787
if (isHTMLCollection(sourceObj)) {
8888
>isHTMLCollection(sourceObj) : boolean
8989
>isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection
90-
>sourceObj : EventTargetLike
90+
>sourceObj : NodeList | HTMLCollection | { a: string; }
9191

9292
sourceObj.length;
9393
>sourceObj.length : number
@@ -99,7 +99,7 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) {
9999
>isNodeList(sourceObj) || isHTMLCollection(sourceObj) : boolean
100100
>isNodeList(sourceObj) : boolean
101101
>isNodeList : (sourceObj: any) => sourceObj is NodeList
102-
>sourceObj : EventTargetLike
102+
>sourceObj : NodeList | HTMLCollection | { a: string; }
103103
>isHTMLCollection(sourceObj) : boolean
104104
>isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection
105105
>sourceObj : HTMLCollection | { a: string; }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [declarationEmitArrayTypesFromGenericArrayUsage.ts]
2+
interface A extends Array<string> { }
3+
4+
5+
//// [declarationEmitArrayTypesFromGenericArrayUsage.js]
6+
7+
8+
//// [declarationEmitArrayTypesFromGenericArrayUsage.d.ts]
9+
interface A extends Array<string> {
10+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/declarationEmitArrayTypesFromGenericArrayUsage.ts ===
2+
interface A extends Array<string> { }
3+
>A : Symbol(A, Decl(declarationEmitArrayTypesFromGenericArrayUsage.ts, 0, 0))
4+
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
5+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/declarationEmitArrayTypesFromGenericArrayUsage.ts ===
2+
interface A extends Array<string> { }
3+
>A : A
4+
>Array : T[]
5+

tests/baselines/reference/declarationEmit_bindingPatterns.js renamed to tests/baselines/reference/declarationEmitBindingPatterns.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
//// [declarationEmit_bindingPatterns.ts]
1+
//// [declarationEmitBindingPatterns.ts]
22

33
const k = ({x: z = 'y'}) => { }
44

55
var a;
66
function f({} = a, [] = a, { p: {} = a} = a) {
77
}
88

9-
//// [declarationEmit_bindingPatterns.js]
9+
//// [declarationEmitBindingPatterns.js]
1010
var k = function (_a) {
1111
var _b = _a.x, z = _b === void 0 ? 'y' : _b;
1212
};
@@ -18,7 +18,7 @@ function f(_a, _b, _c) {
1818
}
1919

2020

21-
//// [declarationEmit_bindingPatterns.d.ts]
21+
//// [declarationEmitBindingPatterns.d.ts]
2222
declare const k: ({x: z}: {
2323
x?: string;
2424
}) => void;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/declarationEmitBindingPatterns.ts ===
2+
3+
const k = ({x: z = 'y'}) => { }
4+
>k : Symbol(k, Decl(declarationEmitBindingPatterns.ts, 1, 5))
5+
>x : Symbol(x)
6+
>z : Symbol(z, Decl(declarationEmitBindingPatterns.ts, 1, 12))
7+
8+
var a;
9+
>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3))
10+
11+
function f({} = a, [] = a, { p: {} = a} = a) {
12+
>f : Symbol(f, Decl(declarationEmitBindingPatterns.ts, 3, 6))
13+
>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3))
14+
>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3))
15+
>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3))
16+
>a : Symbol(a, Decl(declarationEmitBindingPatterns.ts, 3, 3))
17+
}

tests/baselines/reference/declarationEmit_bindingPatterns.types renamed to tests/baselines/reference/declarationEmitBindingPatterns.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
=== tests/cases/compiler/declarationEmit_bindingPatterns.ts ===
1+
=== tests/cases/compiler/declarationEmitBindingPatterns.ts ===
22

33
const k = ({x: z = 'y'}) => { }
44
>k : ({x: z}: { x?: string; }) => void

0 commit comments

Comments
 (0)