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

Port #41467 to release-4.1 #41500

Merged
merged 2 commits into from Nov 11, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/compiler/checker.ts
Expand Up @@ -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
}

Expand Down
12 changes: 12 additions & 0 deletions src/compiler/utilities.ts
Expand Up @@ -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,
Expand Down
37 changes: 37 additions & 0 deletions src/testRunner/unittests/tsc/incremental.ts
Expand Up @@ -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"]
});
});
}
@@ -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"
}

@@ -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"
}