Cherry-pick #37064 into release-3.8 (#37096)

* Fix renaming an ExportSpecifier name when propertyName is present (#36790)

* Fix renaming exportSpecifier name when propertyName is present

* Add baseline test for name without propertyName too

* Set correct pos for NamespaceExport (#36794)

* Set correct pos for NamespaceExport

* Update tests

* Cherry-pick PR #37064 into release-3.8
This commit is contained in:
Andrew Branch 2020-02-28 08:26:28 -08:00 committed by GitHub
parent 963c1f0fce
commit d8765643fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 164 additions and 4 deletions

View File

@ -1922,10 +1922,11 @@ namespace ts {
if (!isValidTypeOnlyAliasUseSite(useSite)) {
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(symbol);
if (typeOnlyDeclaration) {
const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
const isExport = typeOnlyDeclarationIsExport(typeOnlyDeclaration);
const message = isExport
? Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type
: Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type;
const relatedMessage = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
const relatedMessage = isExport
? Diagnostics._0_was_exported_here
: Diagnostics._0_was_imported_here;
const unescapedName = unescapeLeadingUnderscores(name);
@ -2272,12 +2273,14 @@ namespace ts {
function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node: ImportEqualsDeclaration, resolved: Symbol | undefined) {
if (markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false)) {
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(getSymbolOfNode(node))!;
const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
const isExport = typeOnlyDeclarationIsExport(typeOnlyDeclaration);
const message = isExport
? Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type
: Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type;
const relatedMessage = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
const relatedMessage = isExport
? Diagnostics._0_was_exported_here
: Diagnostics._0_was_imported_here;
// Non-null assertion is safe because the optionality comes from ImportClause,
// but if an ImportClause was the typeOnlyDeclaration, it had to have a `name`.
const name = unescapeLeadingUnderscores(typeOnlyDeclaration.name!.escapedText);
@ -33360,6 +33363,7 @@ namespace ts {
grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers);
}
checkGrammarExportDeclaration(node);
if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
if (node.exportClause) {
// export { x, y }
@ -33392,6 +33396,14 @@ namespace ts {
}
}
function checkGrammarExportDeclaration(node: ExportDeclaration): boolean {
const isTypeOnlyExportStar = node.isTypeOnly && node.exportClause?.kind !== SyntaxKind.NamedExports;
if (isTypeOnlyExportStar) {
grammarErrorOnNode(node, Diagnostics.Only_named_exports_may_use_export_type);
}
return !isTypeOnlyExportStar;
}
function checkGrammarModuleElementContext(node: Statement, errorMessage: DiagnosticMessage): boolean {
const isInAppropriateContext = node.parent.kind === SyntaxKind.SourceFile || node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.ModuleDeclaration;
if (!isInAppropriateContext) {

View File

@ -1135,6 +1135,10 @@
"category": "Error",
"code": 1380
},
"Only named exports may use 'export type'.": {
"category": "Error",
"code": 1383
},
"The types of '{0}' are incompatible between these types.": {
"category": "Error",

View File

@ -6172,6 +6172,10 @@ namespace ts {
|| !isExpressionNode(useSite);
}
export function typeOnlyDeclarationIsExport(typeOnlyDeclaration: Node) {
return typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier;
}
function isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(node: Node) {
while (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) {
node = node.parent;

View File

@ -0,0 +1,25 @@
tests/cases/conformance/externalModules/typeOnly/b.ts(1,1): error TS1383: Only named exports may use 'export type'.
tests/cases/conformance/externalModules/typeOnly/c.ts(1,1): error TS1383: Only named exports may use 'export type'.
==== tests/cases/conformance/externalModules/typeOnly/a.ts (0 errors) ====
export class A {}
==== tests/cases/conformance/externalModules/typeOnly/b.ts (1 errors) ====
export type * from './a'; // Grammar error
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS1383: Only named exports may use 'export type'.
==== tests/cases/conformance/externalModules/typeOnly/c.ts (1 errors) ====
export type * as ns from './a'; // Grammar error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS1383: Only named exports may use 'export type'.
==== tests/cases/conformance/externalModules/typeOnly/d.ts (0 errors) ====
import { A } from './b';
A;
==== tests/cases/conformance/externalModules/typeOnly/e.ts (0 errors) ====
import { ns } from './c';
ns.A;

View File

@ -0,0 +1,45 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportNamespace4.ts] ////
//// [a.ts]
export class A {}
//// [b.ts]
export type * from './a'; // Grammar error
//// [c.ts]
export type * as ns from './a'; // Grammar error
//// [d.ts]
import { A } from './b';
A;
//// [e.ts]
import { ns } from './c';
ns.A;
//// [a.js]
"use strict";
exports.__esModule = true;
var A = /** @class */ (function () {
function A() {
}
return A;
}());
exports.A = A;
//// [b.js]
"use strict";
exports.__esModule = true;
//// [c.js]
"use strict";
exports.__esModule = true;
//// [d.js]
"use strict";
exports.__esModule = true;
var b_1 = require("./b");
b_1.A;
//// [e.js]
"use strict";
exports.__esModule = true;
var c_1 = require("./c");
c_1.ns.A;

View File

@ -0,0 +1,27 @@
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
export class A {}
>A : Symbol(A, Decl(a.ts, 0, 0))
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
export type * from './a'; // Grammar error
No type information for this code.
No type information for this code.=== tests/cases/conformance/externalModules/typeOnly/c.ts ===
export type * as ns from './a'; // Grammar error
>ns : Symbol(ns, Decl(c.ts, 0, 11))
=== tests/cases/conformance/externalModules/typeOnly/d.ts ===
import { A } from './b';
>A : Symbol(A, Decl(d.ts, 0, 8))
A;
>A : Symbol(A, Decl(d.ts, 0, 8))
=== tests/cases/conformance/externalModules/typeOnly/e.ts ===
import { ns } from './c';
>ns : Symbol(ns, Decl(e.ts, 0, 8))
ns.A;
>ns.A : Symbol(ns.A, Decl(a.ts, 0, 0))
>ns : Symbol(ns, Decl(e.ts, 0, 8))
>A : Symbol(ns.A, Decl(a.ts, 0, 0))

View File

@ -0,0 +1,27 @@
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
export class A {}
>A : A
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
export type * from './a'; // Grammar error
No type information for this code.
No type information for this code.=== tests/cases/conformance/externalModules/typeOnly/c.ts ===
export type * as ns from './a'; // Grammar error
>ns : typeof ns
=== tests/cases/conformance/externalModules/typeOnly/d.ts ===
import { A } from './b';
>A : typeof A
A;
>A : typeof A
=== tests/cases/conformance/externalModules/typeOnly/e.ts ===
import { ns } from './c';
>ns : typeof ns
ns.A;
>ns.A : typeof ns.A
>ns : typeof ns
>A : typeof ns.A

View File

@ -0,0 +1,16 @@
// @Filename: a.ts
export class A {}
// @Filename: b.ts
export type * from './a'; // Grammar error
// @Filename: c.ts
export type * as ns from './a'; // Grammar error
// @Filename: d.ts
import { A } from './b';
A;
// @Filename: e.ts
import { ns } from './c';
ns.A;