mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Fix crash when importsNotUsedAsValues is set alongside verbatimModuleSyntax (#53386)
This commit is contained in:
parent
af00915d71
commit
001aa99734
@ -1472,6 +1472,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
var argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String);
|
||||
var requireSymbol = createSymbol(SymbolFlags.Property, "require" as __String);
|
||||
var isolatedModulesLikeFlagName = compilerOptions.verbatimModuleSyntax ? "verbatimModuleSyntax" : "isolatedModules";
|
||||
// It is an error to use `importsNotUsedAsValues` alongside `verbatimModuleSyntax`, but we still need to not crash.
|
||||
// Given that, in such a scenario, `verbatimModuleSyntax` is basically disabled, as least as far as alias visibility tracking goes.
|
||||
var canCollectSymbolAliasAccessabilityData = !compilerOptions.verbatimModuleSyntax || !!compilerOptions.importsNotUsedAsValues;
|
||||
|
||||
/** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
|
||||
var apparentArgumentCount: number | undefined;
|
||||
@ -4540,7 +4543,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function markExportAsReferenced(node: ImportEqualsDeclaration | ExportSpecifier) {
|
||||
if (compilerOptions.verbatimModuleSyntax) {
|
||||
if (!canCollectSymbolAliasAccessabilityData) {
|
||||
return;
|
||||
}
|
||||
const symbol = getSymbolOfDeclaration(node);
|
||||
@ -4559,7 +4562,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
|
||||
// the alias as an expression (which recursively takes us back here if the target references another alias).
|
||||
function markAliasSymbolAsReferenced(symbol: Symbol) {
|
||||
Debug.assert(!compilerOptions.verbatimModuleSyntax);
|
||||
Debug.assert(canCollectSymbolAliasAccessabilityData);
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.referenced) {
|
||||
links.referenced = true;
|
||||
@ -27636,7 +27639,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function markAliasReferenced(symbol: Symbol, location: Node) {
|
||||
if (compilerOptions.verbatimModuleSyntax) {
|
||||
if (!canCollectSymbolAliasAccessabilityData) {
|
||||
return;
|
||||
}
|
||||
if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && !getTypeOnlyAliasDeclaration(symbol, SymbolFlags.Value)) {
|
||||
@ -30786,7 +30789,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
jsxFactorySym.isReferenced = SymbolFlags.All;
|
||||
|
||||
// If react/jsxFactory symbol is alias, mark it as refereced
|
||||
if (!compilerOptions.verbatimModuleSyntax && jsxFactorySym.flags & SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) {
|
||||
if (canCollectSymbolAliasAccessabilityData && jsxFactorySym.flags & SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) {
|
||||
markAliasSymbolAsReferenced(jsxFactorySym);
|
||||
}
|
||||
}
|
||||
@ -39723,7 +39726,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const meaning = (typeName.kind === SyntaxKind.Identifier ? SymbolFlags.Type : SymbolFlags.Namespace) | SymbolFlags.Alias;
|
||||
const rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isReference*/ true);
|
||||
if (rootSymbol && rootSymbol.flags & SymbolFlags.Alias) {
|
||||
if (!compilerOptions.verbatimModuleSyntax
|
||||
if (canCollectSymbolAliasAccessabilityData
|
||||
&& symbolIsValue(rootSymbol)
|
||||
&& !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))
|
||||
&& !getTypeOnlyAliasDeclaration(rootSymbol)) {
|
||||
@ -44240,6 +44243,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function checkImportsForTypeOnlyConversion(sourceFile: SourceFile) {
|
||||
if (!canCollectSymbolAliasAccessabilityData) {
|
||||
return;
|
||||
}
|
||||
for (const statement of sourceFile.statements) {
|
||||
if (canConvertImportDeclarationToTypeOnly(statement) || canConvertImportEqualsDeclarationToTypeOnly(statement)) {
|
||||
error(
|
||||
@ -45962,7 +45968,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function isValueAliasDeclaration(node: Node): boolean {
|
||||
Debug.assert(!compilerOptions.verbatimModuleSyntax);
|
||||
Debug.assert(canCollectSymbolAliasAccessabilityData);
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return isAliasResolvedToValue(getSymbolOfDeclaration(node as ImportEqualsDeclaration));
|
||||
@ -46016,7 +46022,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean {
|
||||
Debug.assert(!compilerOptions.verbatimModuleSyntax);
|
||||
Debug.assert(canCollectSymbolAliasAccessabilityData);
|
||||
if (isAliasSymbolDeclaration(node)) {
|
||||
const symbol = getSymbolOfDeclaration(node as Declaration);
|
||||
const links = symbol && getSymbolLinks(symbol);
|
||||
@ -46390,13 +46396,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
isValueAliasDeclaration: nodeIn => {
|
||||
const node = getParseTreeNode(nodeIn);
|
||||
// Synthesized nodes are always treated like values.
|
||||
return node ? isValueAliasDeclaration(node) : true;
|
||||
return node && canCollectSymbolAliasAccessabilityData ? isValueAliasDeclaration(node) : true;
|
||||
},
|
||||
hasGlobalName,
|
||||
isReferencedAliasDeclaration: (nodeIn, checkChildren?) => {
|
||||
const node = getParseTreeNode(nodeIn);
|
||||
// Synthesized nodes are always treated as referenced.
|
||||
return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
|
||||
return node && canCollectSymbolAliasAccessabilityData ? isReferencedAliasDeclaration(node, checkChildren) : true;
|
||||
},
|
||||
getNodeCheckFlags: nodeIn => {
|
||||
const node = getParseTreeNode(nodeIn);
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
error TS5104: Option 'importsNotUsedAsValues' is redundant and cannot be specified with option 'verbatimModuleSyntax'.
|
||||
tests/cases/compiler/file.ts(1,1): error TS1287: A top-level 'export' modifier cannot be used on value declarations in a CommonJS module when 'verbatimModuleSyntax' is enabled.
|
||||
tests/cases/compiler/index.ts(1,1): error TS1371: This import is never used as a value and must use 'import type' because 'importsNotUsedAsValues' is set to 'error'.
|
||||
tests/cases/compiler/index.ts(1,9): error TS1286: ESM syntax is not allowed in a CommonJS module when 'verbatimModuleSyntax' is enabled.
|
||||
|
||||
|
||||
!!! error TS5104: Option 'importsNotUsedAsValues' is redundant and cannot be specified with option 'verbatimModuleSyntax'.
|
||||
==== tests/cases/compiler/file.ts (1 errors) ====
|
||||
export class A {}
|
||||
~~~~~~
|
||||
!!! error TS1287: A top-level 'export' modifier cannot be used on value declarations in a CommonJS module when 'verbatimModuleSyntax' is enabled.
|
||||
==== tests/cases/compiler/index.ts (2 errors) ====
|
||||
import {A} from "./file";
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1371: This import is never used as a value and must use 'import type' because 'importsNotUsedAsValues' is set to 'error'.
|
||||
~
|
||||
!!! error TS1286: ESM syntax is not allowed in a CommonJS module when 'verbatimModuleSyntax' is enabled.
|
||||
|
||||
const a: A = null as any;
|
||||
@ -0,0 +1,24 @@
|
||||
//// [tests/cases/compiler/noCrashWithVerbatimModuleSyntaxAndImportsNotUsedAsValues.ts] ////
|
||||
|
||||
//// [file.ts]
|
||||
export class A {}
|
||||
//// [index.ts]
|
||||
import {A} from "./file";
|
||||
|
||||
const a: A = null as any;
|
||||
|
||||
//// [file.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.A = void 0;
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
exports.A = A;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var file_1 = require("./file");
|
||||
var a = null;
|
||||
@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file.ts ===
|
||||
export class A {}
|
||||
>A : Symbol(A, Decl(file.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import {A} from "./file";
|
||||
>A : Symbol(A, Decl(index.ts, 0, 8))
|
||||
|
||||
const a: A = null as any;
|
||||
>a : Symbol(a, Decl(index.ts, 2, 5))
|
||||
>A : Symbol(A, Decl(index.ts, 0, 8))
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/file.ts ===
|
||||
export class A {}
|
||||
>A : A
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import {A} from "./file";
|
||||
>A : typeof A
|
||||
|
||||
const a: A = null as any;
|
||||
>a : A
|
||||
>null as any : any
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
// @verbatimModuleSyntax: true
|
||||
// @importsNotUsedAsValues: error
|
||||
// @ignoreDeprecations: 5.0
|
||||
// @filename: file.ts
|
||||
export class A {}
|
||||
// @filename: index.ts
|
||||
import {A} from "./file";
|
||||
|
||||
const a: A = null as any;
|
||||
Loading…
x
Reference in New Issue
Block a user