treat ambient non-aliased 'require' as commonjs 'require'
This commit is contained in:
parent
cef9d85979
commit
b7ea3e5bdd
|
@ -12819,16 +12819,41 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
// In JavaScript files, calls to any identifier 'require' are treated as external module imports
|
// In JavaScript files, calls to any identifier 'require' are treated as external module imports
|
||||||
if (isInJavaScriptFile(node) &&
|
if (isInJavaScriptFile(node) && isCommonJsRequire(node)) {
|
||||||
isRequireCall(node, /*checkArgumentIsStringLiteral*/true) &&
|
|
||||||
// Make sure require is not a local function
|
|
||||||
!resolveName(node.expression, (<Identifier>node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) {
|
|
||||||
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
|
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getReturnTypeOfSignature(signature);
|
return getReturnTypeOfSignature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCommonJsRequire(node: Node) {
|
||||||
|
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Make sure require is not a local function
|
||||||
|
const resolvedRequire = resolveName(node.expression, (<Identifier>node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
|
||||||
|
if (!resolvedRequire) {
|
||||||
|
// project does not contain symbol named 'require' - assume commonjs require
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// project includes symbol named 'require' - make sure that it it ambient and local non-alias
|
||||||
|
if (resolvedRequire.flags & SymbolFlags.Alias) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetDeclarationKind = resolvedRequire.flags & SymbolFlags.Function
|
||||||
|
? SyntaxKind.FunctionDeclaration
|
||||||
|
: resolvedRequire.flags & SymbolFlags.Variable
|
||||||
|
? SyntaxKind.VariableDeclaration
|
||||||
|
: SyntaxKind.Unknown;
|
||||||
|
if (targetDeclarationKind !== SyntaxKind.Unknown) {
|
||||||
|
const decl = getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
|
||||||
|
// function/variable declaration should be ambient
|
||||||
|
return isInAmbientContext(decl);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
|
function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
|
||||||
return getReturnTypeOfSignature(getResolvedSignature(node));
|
return getReturnTypeOfSignature(getResolvedSignature(node));
|
||||||
}
|
}
|
||||||
|
|
21
tests/baselines/reference/ambientRequireFunction.js
Normal file
21
tests/baselines/reference/ambientRequireFunction.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//// [tests/cases/compiler/ambientRequireFunction.ts] ////
|
||||||
|
|
||||||
|
//// [node.d.ts]
|
||||||
|
|
||||||
|
|
||||||
|
declare function require(moduleName: string): any;
|
||||||
|
|
||||||
|
declare module "fs" {
|
||||||
|
export function readFileSync(s: string): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// [app.js]
|
||||||
|
/// <reference path="node.d.ts"/>
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
||||||
|
|
||||||
|
//// [app.js]
|
||||||
|
/// <reference path="node.d.ts"/>
|
||||||
|
var fs = require("fs");
|
||||||
|
var text = fs.readFileSync("/a/b/c");
|
27
tests/baselines/reference/ambientRequireFunction.symbols
Normal file
27
tests/baselines/reference/ambientRequireFunction.symbols
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
=== tests/cases/compiler/app.js ===
|
||||||
|
/// <reference path="node.d.ts"/>
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
>fs : Symbol(fs, Decl(app.js, 2, 5))
|
||||||
|
>require : Symbol(require, Decl(node.d.ts, 0, 0))
|
||||||
|
>"fs" : Symbol("fs", Decl(node.d.ts, 2, 50))
|
||||||
|
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
||||||
|
>text : Symbol(text, Decl(app.js, 3, 5))
|
||||||
|
>fs.readFileSync : Symbol(readFileSync, Decl(node.d.ts, 4, 21))
|
||||||
|
>fs : Symbol(fs, Decl(app.js, 2, 5))
|
||||||
|
>readFileSync : Symbol(readFileSync, Decl(node.d.ts, 4, 21))
|
||||||
|
|
||||||
|
=== tests/cases/compiler/node.d.ts ===
|
||||||
|
|
||||||
|
|
||||||
|
declare function require(moduleName: string): any;
|
||||||
|
>require : Symbol(require, Decl(node.d.ts, 0, 0))
|
||||||
|
>moduleName : Symbol(moduleName, Decl(node.d.ts, 2, 25))
|
||||||
|
|
||||||
|
declare module "fs" {
|
||||||
|
export function readFileSync(s: string): string;
|
||||||
|
>readFileSync : Symbol(readFileSync, Decl(node.d.ts, 4, 21))
|
||||||
|
>s : Symbol(s, Decl(node.d.ts, 5, 33))
|
||||||
|
}
|
||||||
|
|
30
tests/baselines/reference/ambientRequireFunction.types
Normal file
30
tests/baselines/reference/ambientRequireFunction.types
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
=== tests/cases/compiler/app.js ===
|
||||||
|
/// <reference path="node.d.ts"/>
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
>fs : typeof "fs"
|
||||||
|
>require("fs") : typeof "fs"
|
||||||
|
>require : (moduleName: string) => any
|
||||||
|
>"fs" : "fs"
|
||||||
|
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
||||||
|
>text : string
|
||||||
|
>fs.readFileSync("/a/b/c") : string
|
||||||
|
>fs.readFileSync : (s: string) => string
|
||||||
|
>fs : typeof "fs"
|
||||||
|
>readFileSync : (s: string) => string
|
||||||
|
>"/a/b/c" : "/a/b/c"
|
||||||
|
|
||||||
|
=== tests/cases/compiler/node.d.ts ===
|
||||||
|
|
||||||
|
|
||||||
|
declare function require(moduleName: string): any;
|
||||||
|
>require : (moduleName: string) => any
|
||||||
|
>moduleName : string
|
||||||
|
|
||||||
|
declare module "fs" {
|
||||||
|
export function readFileSync(s: string): string;
|
||||||
|
>readFileSync : (s: string) => string
|
||||||
|
>s : string
|
||||||
|
}
|
||||||
|
|
15
tests/baselines/reference/localRequireFunction.js
Normal file
15
tests/baselines/reference/localRequireFunction.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//// [app.js]
|
||||||
|
|
||||||
|
function require(a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
||||||
|
|
||||||
|
//// [app.js]
|
||||||
|
function require(a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
var fs = require("fs");
|
||||||
|
var text = fs.readFileSync("/a/b/c");
|
18
tests/baselines/reference/localRequireFunction.symbols
Normal file
18
tests/baselines/reference/localRequireFunction.symbols
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
=== tests/cases/compiler/app.js ===
|
||||||
|
|
||||||
|
function require(a) {
|
||||||
|
>require : Symbol(require, Decl(app.js, 0, 0))
|
||||||
|
>a : Symbol(a, Decl(app.js, 1, 17))
|
||||||
|
|
||||||
|
return a;
|
||||||
|
>a : Symbol(a, Decl(app.js, 1, 17))
|
||||||
|
}
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
>fs : Symbol(fs, Decl(app.js, 5, 5))
|
||||||
|
>require : Symbol(require, Decl(app.js, 0, 0))
|
||||||
|
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
||||||
|
>text : Symbol(text, Decl(app.js, 6, 5))
|
||||||
|
>fs : Symbol(fs, Decl(app.js, 5, 5))
|
||||||
|
|
24
tests/baselines/reference/localRequireFunction.types
Normal file
24
tests/baselines/reference/localRequireFunction.types
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
=== tests/cases/compiler/app.js ===
|
||||||
|
|
||||||
|
function require(a) {
|
||||||
|
>require : (a: any) => any
|
||||||
|
>a : any
|
||||||
|
|
||||||
|
return a;
|
||||||
|
>a : any
|
||||||
|
}
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
>fs : any
|
||||||
|
>require("fs") : any
|
||||||
|
>require : (a: any) => any
|
||||||
|
>"fs" : "fs"
|
||||||
|
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
||||||
|
>text : any
|
||||||
|
>fs.readFileSync("/a/b/c") : any
|
||||||
|
>fs.readFileSync : any
|
||||||
|
>fs : any
|
||||||
|
>readFileSync : any
|
||||||
|
>"/a/b/c" : "/a/b/c"
|
||||||
|
|
17
tests/cases/compiler/ambientRequireFunction.ts
Normal file
17
tests/cases/compiler/ambientRequireFunction.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// @module: commonjs
|
||||||
|
// @allowJs: true
|
||||||
|
// @outDir: ./out/
|
||||||
|
|
||||||
|
// @filename: node.d.ts
|
||||||
|
|
||||||
|
declare function require(moduleName: string): any;
|
||||||
|
|
||||||
|
declare module "fs" {
|
||||||
|
export function readFileSync(s: string): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @filename: app.js
|
||||||
|
/// <reference path="node.d.ts"/>
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
11
tests/cases/compiler/localRequireFunction.ts
Normal file
11
tests/cases/compiler/localRequireFunction.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// @module: commonjs
|
||||||
|
// @allowJs: true
|
||||||
|
// @outDir: ./out/
|
||||||
|
|
||||||
|
// @filename: app.js
|
||||||
|
function require(a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const text = fs.readFileSync("/a/b/c");
|
|
@ -128,7 +128,7 @@ function dir(dirPath: string, spec?: string, options?: any) {
|
||||||
// fs.rmdirSync won't delete directories with files in it
|
// fs.rmdirSync won't delete directories with files in it
|
||||||
function deleteFolderRecursive(dirPath: string) {
|
function deleteFolderRecursive(dirPath: string) {
|
||||||
if (fs.existsSync(dirPath)) {
|
if (fs.existsSync(dirPath)) {
|
||||||
fs.readdirSync(dirPath).forEach((file, index) => {
|
fs.readdirSync(dirPath).forEach((file) => {
|
||||||
const curPath = path.join(path, file);
|
const curPath = path.join(path, file);
|
||||||
if (fs.statSync(curPath).isDirectory()) { // recurse
|
if (fs.statSync(curPath).isDirectory()) { // recurse
|
||||||
deleteFolderRecursive(curPath);
|
deleteFolderRecursive(curPath);
|
||||||
|
@ -141,7 +141,7 @@ function deleteFolderRecursive(dirPath: string) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function writeFile(path: string, data: any, opts: { recursive: boolean }) {
|
function writeFile(path: string, data: any) {
|
||||||
ensureDirectoriesExist(getDirectoryPath(path));
|
ensureDirectoriesExist(getDirectoryPath(path));
|
||||||
fs.writeFileSync(path, data);
|
fs.writeFileSync(path, data);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ enum RequestType {
|
||||||
Unknown
|
Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRequestOperation(req: http.ServerRequest, filename: string) {
|
function getRequestOperation(req: http.ServerRequest) {
|
||||||
if (req.method === "GET" && req.url.indexOf("?") === -1) {
|
if (req.method === "GET" && req.url.indexOf("?") === -1) {
|
||||||
if (req.url.indexOf(".") !== -1) return RequestType.GetFile;
|
if (req.url.indexOf(".") !== -1) return RequestType.GetFile;
|
||||||
else return RequestType.GetDir;
|
else return RequestType.GetDir;
|
||||||
|
@ -258,7 +258,7 @@ function handleRequestOperation(req: http.ServerRequest, res: http.ServerRespons
|
||||||
break;
|
break;
|
||||||
case RequestType.WriteFile:
|
case RequestType.WriteFile:
|
||||||
processPost(req, res, (data) => {
|
processPost(req, res, (data) => {
|
||||||
writeFile(reqPath, data, { recursive: true });
|
writeFile(reqPath, data);
|
||||||
});
|
});
|
||||||
send(ResponseCode.Success, res, undefined);
|
send(ResponseCode.Success, res, undefined);
|
||||||
break;
|
break;
|
||||||
|
@ -306,7 +306,7 @@ http.createServer((req: http.ServerRequest, res: http.ServerResponse) => {
|
||||||
log(`${req.method} ${req.url}`);
|
log(`${req.method} ${req.url}`);
|
||||||
const uri = url.parse(req.url).pathname;
|
const uri = url.parse(req.url).pathname;
|
||||||
const reqPath = path.join(process.cwd(), uri);
|
const reqPath = path.join(process.cwd(), uri);
|
||||||
const operation = getRequestOperation(req, reqPath);
|
const operation = getRequestOperation(req);
|
||||||
handleRequestOperation(req, res, operation, reqPath);
|
handleRequestOperation(req, res, operation, reqPath);
|
||||||
}).listen(port);
|
}).listen(port);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue