Merge pull request #41500 from weswigham/pick-crash-fix

Port #41467 to `release-4.1`
This commit is contained in:
Wesley Wigham 2020-11-11 13:51:18 -08:00 committed by GitHub
commit 612c19d755
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 268 additions and 0 deletions

View File

@ -1091,6 +1091,16 @@ namespace ts {
}
}
function errorOrSuggestion(isError: boolean, location: Node, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void {
// Pseudo-synthesized input node
if (location.pos < 0 || location.end < 0) {
if (!isError) {
return; // Drop suggestions (we have no span to suggest on)
}
// Issue errors globally
const file = getSourceFileOfNode(location);
addErrorOrSuggestion(isError, "message" in message ? createFileDiagnostic(file, 0, 0, message, arg0, arg1, arg2, arg3) : createDiagnosticForFileFromMessageChain(file, message)); // eslint-disable-line no-in-operator
return;
}
addErrorOrSuggestion(isError, "message" in message ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : createDiagnosticForNodeFromMessageChain(location, message)); // eslint-disable-line no-in-operator
}

View File

@ -989,6 +989,18 @@ namespace ts {
};
}
export function createDiagnosticForFileFromMessageChain(sourceFile: SourceFile, messageChain: DiagnosticMessageChain, relatedInformation?: DiagnosticRelatedInformation[]): DiagnosticWithLocation {
return {
file: sourceFile,
start: 0,
length: 0,
code: messageChain.code,
category: messageChain.category,
messageText: messageChain.next ? messageChain : messageChain.messageText,
relatedInformation
};
}
export function createDiagnosticForRange(sourceFile: SourceFile, range: TextRange, message: DiagnosticMessage): DiagnosticWithLocation {
return {
file: sourceFile,

View File

@ -235,5 +235,42 @@ const a: string = 10;`, "utf-8"),
}
}
});
const jsxLibraryContent = `
export {};
declare global {
namespace JSX {
interface Element {}
interface IntrinsicElements {
div: {
propA?: boolean;
};
}
}
}`;
verifyTsc({
scenario: "react-jsx-emit-mode",
subScenario: "with no backing types found doesn't crash",
fs: () => loadProjectFromFiles({
"/src/project/node_modules/react/jsx-runtime.js": "export {}", // js needs to be present so there's a resolution result
"/src/project/node_modules/@types/react/index.d.ts": jsxLibraryContent, // doesn't contain a jsx-runtime definition
"/src/project/src/index.tsx": `export const App = () => <div propA={true}></div>;`,
"/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react" } })
}),
commandLineArgs: ["--p", "src/project"]
});
verifyTsc({
scenario: "react-jsx-emit-mode",
subScenario: "with no backing types found doesn't crash under --strict",
fs: () => loadProjectFromFiles({
"/src/project/node_modules/react/jsx-runtime.js": "export {}", // js needs to be present so there's a resolution result
"/src/project/node_modules/@types/react/index.d.ts": jsxLibraryContent, // doesn't contain a jsx-runtime definition
"/src/project/src/index.tsx": `export const App = () => <div propA={true}></div>;`,
"/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { module: "commonjs", jsx: "react-jsx", incremental: true, jsxImportSource: "react" } })
}),
commandLineArgs: ["--p", "src/project", "--strict"]
});
});
}

View File

@ -0,0 +1,115 @@
Input::
//// [/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };
//// [/src/project/node_modules/@types/react/index.d.ts]
export {};
declare global {
namespace JSX {
interface Element {}
interface IntrinsicElements {
div: {
propA?: boolean;
};
}
}
}
//// [/src/project/node_modules/react/jsx-runtime.js]
//// [/src/project/src/index.tsx]
export const App = () => <div propA={true}></div>;
//// [/src/project/tsconfig.json]
{"compilerOptions":{"module":"commonjs","jsx":"react-jsx","incremental":true,"jsxImportSource":"react"}}
Output::
/lib/tsc --p src/project --strict
src/project/src/index.tsx:1:26 - error TS7016: Could not find a declaration file for module 'react/jsx-runtime'. '/src/project/node_modules/react/jsx-runtime.js' implicitly has an 'any' type.
1 export const App = () => <div propA={true}></div>;
   ~~~~~~~~~~~~~~~~~~~~~~~~
Found 1 error.
exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated
//// [/src/project/src/index.js]
"use strict";
exports.__esModule = true;
exports.App = void 0;
var jsx_runtime_1 = require("react/jsx-runtime");
var App = function () { return jsx_runtime_1.jsx("div", { propA: true }, void 0); };
exports.App = App;
//// [/src/project/tsconfig.tsbuildinfo]
{
"program": {
"fileInfos": {
"../../lib/lib.d.ts": {
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true
},
"./src/index.tsx": {
"version": "-14760199789-export const App = () => <div propA={true}></div>;",
"signature": "-8716173275-/// <reference types=\"react\" />\r\nexport declare const App: () => JSX.Element;\r\n",
"affectsGlobalScope": false
},
"./node_modules/@types/react/index.d.ts": {
"version": "-16587767667-\nexport {};\ndeclare global {\n namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n }\n}",
"signature": "-16587767667-\nexport {};\ndeclare global {\n namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n }\n}",
"affectsGlobalScope": true
}
},
"options": {
"module": 1,
"jsx": 4,
"incremental": true,
"jsxImportSource": "react",
"project": "./",
"strict": true,
"configFilePath": "./tsconfig.json"
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../lib/lib.d.ts",
"./node_modules/@types/react/index.d.ts",
[
"./src/index.tsx",
[
{
"file": "./src/index.tsx",
"start": 25,
"length": 24,
"code": 7016,
"category": 1,
"messageText": "Could not find a declaration file for module 'react/jsx-runtime'. '/src/project/node_modules/react/jsx-runtime.js' implicitly has an 'any' type."
}
]
]
]
},
"version": "FakeTSVersion"
}

View File

@ -0,0 +1,94 @@
Input::
//// [/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };
//// [/src/project/node_modules/@types/react/index.d.ts]
export {};
declare global {
namespace JSX {
interface Element {}
interface IntrinsicElements {
div: {
propA?: boolean;
};
}
}
}
//// [/src/project/node_modules/react/jsx-runtime.js]
//// [/src/project/src/index.tsx]
export const App = () => <div propA={true}></div>;
//// [/src/project/tsconfig.json]
{"compilerOptions":{"module":"commonjs","jsx":"react-jsx","incremental":true,"jsxImportSource":"react"}}
Output::
/lib/tsc --p src/project
exitCode:: ExitStatus.Success
//// [/src/project/src/index.js]
"use strict";
exports.__esModule = true;
exports.App = void 0;
var jsx_runtime_1 = require("react/jsx-runtime");
var App = function () { return jsx_runtime_1.jsx("div", { propA: true }, void 0); };
exports.App = App;
//// [/src/project/tsconfig.tsbuildinfo]
{
"program": {
"fileInfos": {
"../../lib/lib.d.ts": {
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true
},
"./src/index.tsx": {
"version": "-14760199789-export const App = () => <div propA={true}></div>;",
"signature": "-8716173275-/// <reference types=\"react\" />\r\nexport declare const App: () => JSX.Element;\r\n",
"affectsGlobalScope": false
},
"./node_modules/@types/react/index.d.ts": {
"version": "-16587767667-\nexport {};\ndeclare global {\n namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n }\n}",
"signature": "-16587767667-\nexport {};\ndeclare global {\n namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n }\n}",
"affectsGlobalScope": true
}
},
"options": {
"module": 1,
"jsx": 4,
"incremental": true,
"jsxImportSource": "react",
"project": "./",
"configFilePath": "./tsconfig.json"
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../lib/lib.d.ts",
"./node_modules/@types/react/index.d.ts",
"./src/index.tsx"
]
},
"version": "FakeTSVersion"
}