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

Add case to capture enum subtype reduction (addresses #35867) #49675

Merged
merged 1 commit into from
Jun 24, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions tests/baselines/reference/enumMemberReduction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//// [enumMemberReduction.ts]
enum MyEnum {
A,
B,
C,
}

enum MyStringEnum {
A = "a",
B = "b",
C = "c",
}

enum MyStringEnumWithEmpty {
A = "",
B = "b",
C = "c",
}

export function fn(optionalEnum: MyEnum | undefined) {
return optionalEnum ?? MyEnum.A;
}

export function fn2(optionalEnum: MyEnum | undefined) {
return optionalEnum || MyEnum.B;
}

export function fn3(optionalEnum?: MyEnum) {
return optionalEnum ?? MyEnum.A;
}

export function fn4(optionalEnum?: MyEnum) {
return optionalEnum || MyEnum.B;
}

export function fn5(optionalEnum?: MyStringEnum) {
return optionalEnum || MyStringEnum.B;
}

export function fn6(optionalEnum?: MyStringEnumWithEmpty) {
return optionalEnum || MyStringEnumWithEmpty.B;
}


//// [enumMemberReduction.js]
"use strict";
exports.__esModule = true;
exports.fn6 = exports.fn5 = exports.fn4 = exports.fn3 = exports.fn2 = exports.fn = void 0;
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["A"] = 0] = "A";
MyEnum[MyEnum["B"] = 1] = "B";
MyEnum[MyEnum["C"] = 2] = "C";
})(MyEnum || (MyEnum = {}));
var MyStringEnum;
(function (MyStringEnum) {
MyStringEnum["A"] = "a";
MyStringEnum["B"] = "b";
MyStringEnum["C"] = "c";
})(MyStringEnum || (MyStringEnum = {}));
var MyStringEnumWithEmpty;
(function (MyStringEnumWithEmpty) {
MyStringEnumWithEmpty["A"] = "";
MyStringEnumWithEmpty["B"] = "b";
MyStringEnumWithEmpty["C"] = "c";
})(MyStringEnumWithEmpty || (MyStringEnumWithEmpty = {}));
function fn(optionalEnum) {
return optionalEnum !== null && optionalEnum !== void 0 ? optionalEnum : MyEnum.A;
}
exports.fn = fn;
function fn2(optionalEnum) {
return optionalEnum || MyEnum.B;
}
exports.fn2 = fn2;
function fn3(optionalEnum) {
return optionalEnum !== null && optionalEnum !== void 0 ? optionalEnum : MyEnum.A;
}
exports.fn3 = fn3;
function fn4(optionalEnum) {
return optionalEnum || MyEnum.B;
}
exports.fn4 = fn4;
function fn5(optionalEnum) {
return optionalEnum || MyStringEnum.B;
}
exports.fn5 = fn5;
function fn6(optionalEnum) {
return optionalEnum || MyStringEnumWithEmpty.B;
}
exports.fn6 = fn6;
112 changes: 112 additions & 0 deletions tests/baselines/reference/enumMemberReduction.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
=== tests/cases/compiler/enumMemberReduction.ts ===
enum MyEnum {
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))

A,
>A : Symbol(MyEnum.A, Decl(enumMemberReduction.ts, 0, 13))

B,
>B : Symbol(MyEnum.B, Decl(enumMemberReduction.ts, 1, 4))

C,
>C : Symbol(MyEnum.C, Decl(enumMemberReduction.ts, 2, 4))
}

enum MyStringEnum {
>MyStringEnum : Symbol(MyStringEnum, Decl(enumMemberReduction.ts, 4, 1))

A = "a",
>A : Symbol(MyStringEnum.A, Decl(enumMemberReduction.ts, 6, 19))

B = "b",
>B : Symbol(MyStringEnum.B, Decl(enumMemberReduction.ts, 7, 10))

C = "c",
>C : Symbol(MyStringEnum.C, Decl(enumMemberReduction.ts, 8, 10))
}

enum MyStringEnumWithEmpty {
>MyStringEnumWithEmpty : Symbol(MyStringEnumWithEmpty, Decl(enumMemberReduction.ts, 10, 1))

A = "",
>A : Symbol(MyStringEnumWithEmpty.A, Decl(enumMemberReduction.ts, 12, 28))

B = "b",
>B : Symbol(MyStringEnumWithEmpty.B, Decl(enumMemberReduction.ts, 13, 9))

C = "c",
>C : Symbol(MyStringEnumWithEmpty.C, Decl(enumMemberReduction.ts, 14, 10))
}

export function fn(optionalEnum: MyEnum | undefined) {
>fn : Symbol(fn, Decl(enumMemberReduction.ts, 16, 1))
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 18, 19))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))

return optionalEnum ?? MyEnum.A;
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 18, 19))
>MyEnum.A : Symbol(MyEnum.A, Decl(enumMemberReduction.ts, 0, 13))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))
>A : Symbol(MyEnum.A, Decl(enumMemberReduction.ts, 0, 13))
}

export function fn2(optionalEnum: MyEnum | undefined) {
>fn2 : Symbol(fn2, Decl(enumMemberReduction.ts, 20, 1))
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 22, 20))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))

return optionalEnum || MyEnum.B;
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 22, 20))
>MyEnum.B : Symbol(MyEnum.B, Decl(enumMemberReduction.ts, 1, 4))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))
>B : Symbol(MyEnum.B, Decl(enumMemberReduction.ts, 1, 4))
}

export function fn3(optionalEnum?: MyEnum) {
>fn3 : Symbol(fn3, Decl(enumMemberReduction.ts, 24, 1))
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 26, 20))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))

return optionalEnum ?? MyEnum.A;
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 26, 20))
>MyEnum.A : Symbol(MyEnum.A, Decl(enumMemberReduction.ts, 0, 13))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))
>A : Symbol(MyEnum.A, Decl(enumMemberReduction.ts, 0, 13))
}

export function fn4(optionalEnum?: MyEnum) {
>fn4 : Symbol(fn4, Decl(enumMemberReduction.ts, 28, 1))
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 30, 20))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))

return optionalEnum || MyEnum.B;
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 30, 20))
>MyEnum.B : Symbol(MyEnum.B, Decl(enumMemberReduction.ts, 1, 4))
>MyEnum : Symbol(MyEnum, Decl(enumMemberReduction.ts, 0, 0))
>B : Symbol(MyEnum.B, Decl(enumMemberReduction.ts, 1, 4))
}

export function fn5(optionalEnum?: MyStringEnum) {
>fn5 : Symbol(fn5, Decl(enumMemberReduction.ts, 32, 1))
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 34, 20))
>MyStringEnum : Symbol(MyStringEnum, Decl(enumMemberReduction.ts, 4, 1))

return optionalEnum || MyStringEnum.B;
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 34, 20))
>MyStringEnum.B : Symbol(MyStringEnum.B, Decl(enumMemberReduction.ts, 7, 10))
>MyStringEnum : Symbol(MyStringEnum, Decl(enumMemberReduction.ts, 4, 1))
>B : Symbol(MyStringEnum.B, Decl(enumMemberReduction.ts, 7, 10))
}

export function fn6(optionalEnum?: MyStringEnumWithEmpty) {
>fn6 : Symbol(fn6, Decl(enumMemberReduction.ts, 36, 1))
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 38, 20))
>MyStringEnumWithEmpty : Symbol(MyStringEnumWithEmpty, Decl(enumMemberReduction.ts, 10, 1))

return optionalEnum || MyStringEnumWithEmpty.B;
>optionalEnum : Symbol(optionalEnum, Decl(enumMemberReduction.ts, 38, 20))
>MyStringEnumWithEmpty.B : Symbol(MyStringEnumWithEmpty.B, Decl(enumMemberReduction.ts, 13, 9))
>MyStringEnumWithEmpty : Symbol(MyStringEnumWithEmpty, Decl(enumMemberReduction.ts, 10, 1))
>B : Symbol(MyStringEnumWithEmpty.B, Decl(enumMemberReduction.ts, 13, 9))
}

118 changes: 118 additions & 0 deletions tests/baselines/reference/enumMemberReduction.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
=== tests/cases/compiler/enumMemberReduction.ts ===
enum MyEnum {
>MyEnum : MyEnum

A,
>A : MyEnum.A

B,
>B : MyEnum.B

C,
>C : MyEnum.C
}

enum MyStringEnum {
>MyStringEnum : MyStringEnum

A = "a",
>A : MyStringEnum.A
>"a" : "a"

B = "b",
>B : MyStringEnum.B
>"b" : "b"

C = "c",
>C : MyStringEnum.C
>"c" : "c"
}

enum MyStringEnumWithEmpty {
>MyStringEnumWithEmpty : MyStringEnumWithEmpty

A = "",
>A : MyStringEnumWithEmpty.A
>"" : ""

B = "b",
>B : MyStringEnumWithEmpty.B
>"b" : "b"

C = "c",
>C : MyStringEnumWithEmpty.C
>"c" : "c"
}

export function fn(optionalEnum: MyEnum | undefined) {
>fn : (optionalEnum: MyEnum | undefined) => MyEnum
>optionalEnum : MyEnum

return optionalEnum ?? MyEnum.A;
>optionalEnum ?? MyEnum.A : MyEnum
>optionalEnum : MyEnum
>MyEnum.A : MyEnum.A
>MyEnum : typeof MyEnum
>A : MyEnum.A
}

export function fn2(optionalEnum: MyEnum | undefined) {
>fn2 : (optionalEnum: MyEnum | undefined) => MyEnum.B | MyEnum.C
>optionalEnum : MyEnum

return optionalEnum || MyEnum.B;
>optionalEnum || MyEnum.B : MyEnum.B | MyEnum.C
>optionalEnum : MyEnum
>MyEnum.B : MyEnum.B
>MyEnum : typeof MyEnum
>B : MyEnum.B
}

export function fn3(optionalEnum?: MyEnum) {
>fn3 : (optionalEnum?: MyEnum) => MyEnum
>optionalEnum : MyEnum

return optionalEnum ?? MyEnum.A;
>optionalEnum ?? MyEnum.A : MyEnum
>optionalEnum : MyEnum
>MyEnum.A : MyEnum.A
>MyEnum : typeof MyEnum
>A : MyEnum.A
}

export function fn4(optionalEnum?: MyEnum) {
>fn4 : (optionalEnum?: MyEnum) => MyEnum.B | MyEnum.C
>optionalEnum : MyEnum

return optionalEnum || MyEnum.B;
>optionalEnum || MyEnum.B : MyEnum.B | MyEnum.C
>optionalEnum : MyEnum
>MyEnum.B : MyEnum.B
>MyEnum : typeof MyEnum
>B : MyEnum.B
}

export function fn5(optionalEnum?: MyStringEnum) {
>fn5 : (optionalEnum?: MyStringEnum) => MyStringEnum
>optionalEnum : MyStringEnum

return optionalEnum || MyStringEnum.B;
>optionalEnum || MyStringEnum.B : MyStringEnum
>optionalEnum : MyStringEnum
>MyStringEnum.B : MyStringEnum.B
>MyStringEnum : typeof MyStringEnum
>B : MyStringEnum.B
}

export function fn6(optionalEnum?: MyStringEnumWithEmpty) {
>fn6 : (optionalEnum?: MyStringEnumWithEmpty) => MyStringEnumWithEmpty.B | MyStringEnumWithEmpty.C
>optionalEnum : MyStringEnumWithEmpty

return optionalEnum || MyStringEnumWithEmpty.B;
>optionalEnum || MyStringEnumWithEmpty.B : MyStringEnumWithEmpty.B | MyStringEnumWithEmpty.C
>optionalEnum : MyStringEnumWithEmpty
>MyStringEnumWithEmpty.B : MyStringEnumWithEmpty.B
>MyStringEnumWithEmpty : typeof MyStringEnumWithEmpty
>B : MyStringEnumWithEmpty.B
}

41 changes: 41 additions & 0 deletions tests/cases/compiler/enumMemberReduction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
enum MyEnum {
A,
B,
C,
}

enum MyStringEnum {
A = "a",
B = "b",
C = "c",
}

enum MyStringEnumWithEmpty {
A = "",
B = "b",
C = "c",
}

export function fn(optionalEnum: MyEnum | undefined) {
return optionalEnum ?? MyEnum.A;
}

export function fn2(optionalEnum: MyEnum | undefined) {
return optionalEnum || MyEnum.B;
}

export function fn3(optionalEnum?: MyEnum) {
return optionalEnum ?? MyEnum.A;
}

export function fn4(optionalEnum?: MyEnum) {
return optionalEnum || MyEnum.B;
}

export function fn5(optionalEnum?: MyStringEnum) {
return optionalEnum || MyStringEnum.B;
}

export function fn6(optionalEnum?: MyStringEnumWithEmpty) {
return optionalEnum || MyStringEnumWithEmpty.B;
}