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

feat(3792): Cannot 'export default' abstract, ambient class or interface #46120

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
eb77b46
feat(3792): allow export default namespaces/modules/enums/types/const…
a-tarasyuk Jun 14, 2022
5f704fa
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Nov 8, 2022
352701f
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Nov 18, 2022
22bf0c1
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Nov 24, 2022
0550088
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Dec 10, 2022
4efcf24
update baseline
a-tarasyuk Dec 10, 2022
e2b8325
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Feb 8, 2023
be6b88b
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Feb 26, 2023
08809dc
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Mar 11, 2023
54a2e86
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Mar 16, 2023
7165a3a
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Apr 25, 2023
21488f9
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Jun 3, 2023
f9fd7d4
remove unused baselines
a-tarasyuk Jun 3, 2023
dc57731
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Jun 20, 2023
c8a8be5
update baseline
a-tarasyuk Jun 20, 2023
92d9e36
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Sep 15, 2023
ce2df3e
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Aug 19, 2024
5087d8d
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Oct 6, 2024
afe50ea
Merge branch 'main' of https:/microsoft/TypeScript into f…
a-tarasyuk Oct 21, 2024
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
39 changes: 33 additions & 6 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2822,12 +2822,27 @@ namespace Parser {

function nextTokenCanFollowDefaultKeyword(): boolean {
nextToken();
return token() === SyntaxKind.ClassKeyword
|| token() === SyntaxKind.FunctionKeyword
|| token() === SyntaxKind.InterfaceKeyword
|| token() === SyntaxKind.AtToken
|| (token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine))
|| (token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
switch (token()) {
case SyntaxKind.ClassKeyword:
case SyntaxKind.InterfaceKeyword:
case SyntaxKind.FunctionKeyword:
case SyntaxKind.NamespaceKeyword:
case SyntaxKind.ModuleKeyword:
case SyntaxKind.EnumKeyword:
case SyntaxKind.ConstKeyword:
case SyntaxKind.AtToken:
return true;
case SyntaxKind.DeclareKeyword:
return lookAhead(nextTokenCanFollowExportDefaultDeclareKeyword);
case SyntaxKind.TypeKeyword:
return lookAhead(nextTokenIsIdentifierOnSameLine);
case SyntaxKind.AbstractKeyword:
return lookAhead(nextTokenIsClassKeywordOnSameLine);
case SyntaxKind.AsyncKeyword:
return lookAhead(nextTokenIsFunctionKeywordOnSameLine);
default:
return false;
}
}

// True if positioned at the start of a list element
Expand Down Expand Up @@ -7142,6 +7157,18 @@ namespace Parser {
return token() === SyntaxKind.ClassKeyword && !scanner.hasPrecedingLineBreak();
}

function nextTokenCanFollowExportDefaultDeclareKeyword() {
nextToken();
switch (token()) {
case SyntaxKind.NamespaceKeyword:
case SyntaxKind.ModuleKeyword:
case SyntaxKind.ClassKeyword:
return !scanner.hasPrecedingLineBreak();
default:
return false;
}
}

function nextTokenIsFunctionKeywordOnSameLine() {
nextToken();
return token() === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak();
Expand Down
249 changes: 82 additions & 167 deletions src/compiler/transformers/ts.ts

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions tests/baselines/reference/exportDefaultConstEnum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//// [tests/cases/compiler/exportDefaultConstEnum.ts] ////

//// [a.ts]
export default const enum A {
A,
B
}

//// [b.ts]
import A from "./a"

A.A;
A.B;


//// [a.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//// [b.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
0 /* A.A */;
1 /* A.B */;
27 changes: 27 additions & 0 deletions tests/baselines/reference/exportDefaultConstEnum.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//// [tests/cases/compiler/exportDefaultConstEnum.ts] ////

=== a.ts ===
export default const enum A {
>A : Symbol(A, Decl(a.ts, 0, 0))

A,
>A : Symbol(A.A, Decl(a.ts, 0, 29))

B
>B : Symbol(A.B, Decl(a.ts, 1, 6))
}

=== b.ts ===
import A from "./a"
>A : Symbol(A, Decl(b.ts, 0, 6))

A.A;
>A.A : Symbol(A.A, Decl(a.ts, 0, 29))
>A : Symbol(A, Decl(b.ts, 0, 6))
>A : Symbol(A.A, Decl(a.ts, 0, 29))

A.B;
>A.B : Symbol(A.B, Decl(a.ts, 1, 6))
>A : Symbol(A, Decl(b.ts, 0, 6))
>B : Symbol(A.B, Decl(a.ts, 1, 6))

37 changes: 37 additions & 0 deletions tests/baselines/reference/exportDefaultConstEnum.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//// [tests/cases/compiler/exportDefaultConstEnum.ts] ////

=== a.ts ===
export default const enum A {
>A : A
> : ^

A,
>A : A.A
> : ^^^

B
>B : A.B
> : ^^^
}

=== b.ts ===
import A from "./a"
>A : typeof A
> : ^^^^^^^^

A.A;
>A.A : A.A
> : ^^^
>A : typeof A
> : ^^^^^^^^
>A : A.A
> : ^^^

A.B;
>A.B : A.B
> : ^^^
>A : typeof A
> : ^^^^^^^^
>B : A.B
> : ^^^

21 changes: 21 additions & 0 deletions tests/baselines/reference/exportDefaultDeclareClass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//// [tests/cases/compiler/exportDefaultDeclareClass.ts] ////

//// [a.ts]
export default declare class C {
public foo: number;
}

//// [b.ts]
import A from "./a"
let a: A;
a.foo


//// [a.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//// [b.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var a;
a.foo;
23 changes: 23 additions & 0 deletions tests/baselines/reference/exportDefaultDeclareClass.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//// [tests/cases/compiler/exportDefaultDeclareClass.ts] ////

=== a.ts ===
export default declare class C {
>C : Symbol(C, Decl(a.ts, 0, 0))

public foo: number;
>foo : Symbol(C.foo, Decl(a.ts, 0, 32))
}

=== b.ts ===
import A from "./a"
>A : Symbol(A, Decl(b.ts, 0, 6))

let a: A;
>a : Symbol(a, Decl(b.ts, 1, 3))
>A : Symbol(A, Decl(b.ts, 0, 6))

a.foo
>a.foo : Symbol(A.foo, Decl(a.ts, 0, 32))
>a : Symbol(a, Decl(b.ts, 1, 3))
>foo : Symbol(A.foo, Decl(a.ts, 0, 32))

29 changes: 29 additions & 0 deletions tests/baselines/reference/exportDefaultDeclareClass.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//// [tests/cases/compiler/exportDefaultDeclareClass.ts] ////

=== a.ts ===
export default declare class C {
>C : C
> : ^

public foo: number;
>foo : number
> : ^^^^^^
}

=== b.ts ===
import A from "./a"
>A : typeof A
> : ^^^^^^^^

let a: A;
>a : A
> : ^

a.foo
>a.foo : number
> : ^^^^^^
>a : A
> : ^
>foo : number
> : ^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//// [tests/cases/compiler/exportDefaultEnum.ts] ////

//// [a.ts]
export default enum A {
A,
B
}

//// [b.ts]
import A from "./a"

A.A;
A.B;


//// [a.js]
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var A = {};
exports.default = A;
(function (A) {
A[A["A"] = 0] = "A";
A[A["B"] = 1] = "B";
})(A);
});
//// [b.js]
define(["require", "exports", "./a"], function (require, exports, a_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
a_1.default.A;
a_1.default.B;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//// [tests/cases/compiler/exportDefaultEnum.ts] ////

=== a.ts ===
export default enum A {
>A : Symbol(A, Decl(a.ts, 0, 0))

A,
>A : Symbol(A.A, Decl(a.ts, 0, 23))

B
>B : Symbol(A.B, Decl(a.ts, 1, 6))
}

=== b.ts ===
import A from "./a"
>A : Symbol(A, Decl(b.ts, 0, 6))

A.A;
>A.A : Symbol(A.A, Decl(a.ts, 0, 23))
>A : Symbol(A, Decl(b.ts, 0, 6))
>A : Symbol(A.A, Decl(a.ts, 0, 23))

A.B;
>A.B : Symbol(A.B, Decl(a.ts, 1, 6))
>A : Symbol(A, Decl(b.ts, 0, 6))
>B : Symbol(A.B, Decl(a.ts, 1, 6))

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//// [tests/cases/compiler/exportDefaultEnum.ts] ////

=== a.ts ===
export default enum A {
>A : A
> : ^

A,
>A : A.A
> : ^^^

B
>B : A.B
> : ^^^
}

=== b.ts ===
import A from "./a"
>A : typeof A
> : ^^^^^^^^

A.A;
>A.A : A.A
> : ^^^
>A : typeof A
> : ^^^^^^^^
>A : A.A
> : ^^^

A.B;
>A.B : A.B
> : ^^^
>A : typeof A
> : ^^^^^^^^
>B : A.B
> : ^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//// [tests/cases/compiler/exportDefaultEnum.ts] ////

//// [a.ts]
export default enum A {
A,
B
}

//// [b.ts]
import A from "./a"

A.A;
A.B;


//// [a.js]
define(["require", "exports"], function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var A = {};
exports.default = A;
(function (A) {
A[A["A"] = 0] = "A";
A[A["B"] = 1] = "B";
})(A);
});
//// [b.js]
define(["require", "exports", "./a"], function (require, exports, a_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
a_1.default.A;
a_1.default.B;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//// [tests/cases/compiler/exportDefaultEnum.ts] ////

=== a.ts ===
export default enum A {
>A : Symbol(A, Decl(a.ts, 0, 0))

A,
>A : Symbol(A.A, Decl(a.ts, 0, 23))

B
>B : Symbol(A.B, Decl(a.ts, 1, 6))
}

=== b.ts ===
import A from "./a"
>A : Symbol(A, Decl(b.ts, 0, 6))

A.A;
>A.A : Symbol(A.A, Decl(a.ts, 0, 23))
>A : Symbol(A, Decl(b.ts, 0, 6))
>A : Symbol(A.A, Decl(a.ts, 0, 23))

A.B;
>A.B : Symbol(A.B, Decl(a.ts, 1, 6))
>A : Symbol(A, Decl(b.ts, 0, 6))
>B : Symbol(A.B, Decl(a.ts, 1, 6))

Loading