Skip to content

Commit dd3bb9c

Browse files
committed
Merge branch 'master' into noImplicitAnyOnCast
2 parents b326065 + e157763 commit dd3bb9c

File tree

212 files changed

+568
-370
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

212 files changed

+568
-370
lines changed

scripts/importDefinitllyTypedTests.ts

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
declare var require: any, process: any;
2+
declare var __dirname: any;
3+
4+
var fs = require("fs");
5+
var path = require("path");
6+
var child_process = require('child_process');
7+
8+
var tscRoot = path.join(__dirname, "..\\");
9+
var tscPath = path.join(tscRoot, "built", "instrumented", "tsc.js");
10+
var rwcTestPath = path.join(tscRoot, "tests", "cases", "rwc", "dt");
11+
var definitelyTypedRoot = process.argv[2];
12+
13+
function fileExtensionIs(path: string, extension: string): boolean {
14+
var pathLen = path.length;
15+
var extLen = extension.length;
16+
return pathLen > extLen && path.substr(pathLen - extLen, extLen).toLocaleLowerCase() === extension.toLocaleLowerCase();
17+
}
18+
19+
function copyFileSync(source, destination) {
20+
var text = fs.readFileSync(source);
21+
fs.writeFileSync(destination, text);
22+
}
23+
24+
function importDefinitelyTypedTest(testCaseName: string, testFiles: string[], responseFile: string ) {
25+
var cmd = "node " + tscPath + " --module commonjs " + testFiles.join(" ");
26+
if (responseFile) cmd += " @" + responseFile;
27+
28+
var testDirectoryName = testCaseName + "_" + Math.floor((Math.random() * 10000) + 1);
29+
var testDirectoryPath = path.join(process.env["temp"], testDirectoryName);
30+
if (fs.existsSync(testDirectoryPath)) {
31+
throw new Error("Could not create test directory");
32+
}
33+
fs.mkdirSync(testDirectoryPath);
34+
35+
child_process.exec(cmd, {
36+
maxBuffer: 1 * 1024 * 1024,
37+
cwd: testDirectoryPath
38+
}, (error, stdout, stderr) => {
39+
//console.log("importing " + testCaseName + " ...");
40+
//console.log(cmd);
41+
42+
if (error) {
43+
console.log("importing " + testCaseName + " ...");
44+
console.log(cmd);
45+
console.log("==> error " + JSON.stringify(error));
46+
console.log("==> stdout " + String(stdout));
47+
console.log("==> stderr " + String(stderr));
48+
console.log("\r\n");
49+
return;
50+
}
51+
52+
// copy generated file to output location
53+
var outputFilePath = path.join(testDirectoryPath, "iocapture0.json");
54+
var testCasePath = path.join(rwcTestPath, "DefinitelyTyped_" + testCaseName + ".json");
55+
copyFileSync(outputFilePath, testCasePath);
56+
57+
//console.log("output generated at: " + outputFilePath);
58+
59+
if (!fs.existsSync(testCasePath)) {
60+
throw new Error("could not find test case at: " + testCasePath);
61+
}
62+
else {
63+
fs.unlinkSync(outputFilePath);
64+
fs.rmdirSync(testDirectoryPath);
65+
//console.log("testcase generated at: " + testCasePath);
66+
//console.log("Done.");
67+
}
68+
//console.log("\r\n");
69+
70+
})
71+
.on('error', function (error) {
72+
console.log("==> error " + JSON.stringify(error));
73+
console.log("\r\n");
74+
});
75+
}
76+
77+
function importDefinitelyTypedTests(definitelyTypedRoot: string): void {
78+
fs.readdir(definitelyTypedRoot, (err, subDirectorys) => {
79+
if (err) throw err;
80+
81+
subDirectorys
82+
.filter(d => ["_infrastructure", "node_modules", ".git"].indexOf(d) >= 0)
83+
.filter(i => fs.statSync(path.join(definitelyTypedRoot, i)).isDirectory())
84+
.forEach(d => {
85+
var directoryPath = path.join(definitelyTypedRoot, d);
86+
fs.readdir(directoryPath, function (err, files) {
87+
if (err) throw err;
88+
89+
var tsFiles = [];
90+
var testFiles = [];
91+
var paramFile;
92+
93+
files
94+
.map(f => path.join(directoryPath, f))
95+
.forEach(f => {
96+
if (fileExtensionIs(f, ".ts")) tsFiles.push(f);
97+
else if (fileExtensionIs(f, ".tscparams")) paramFile = f;
98+
99+
if (fileExtensionIs(f, "-tests.ts")) testFiles.push(f);
100+
});
101+
102+
if (testFiles.length === 0) {
103+
// no test files but multiple d.ts's, e.g. winjs
104+
var regexp = new RegExp(d + "(([-][0-9])|([\.]d[\.]ts))");
105+
if (tsFiles.length > 1 && tsFiles.every(t => fileExtensionIs(t, ".d.ts") && regexp.test(t))) {
106+
tsFiles.forEach(filename => {
107+
importDefinitelyTypedTest(path.basename(filename, ".d.ts"), [filename], paramFile);
108+
});
109+
}
110+
else {
111+
importDefinitelyTypedTest(d, tsFiles, paramFile);
112+
}
113+
}
114+
else {
115+
testFiles.forEach(filename => {
116+
importDefinitelyTypedTest(path.basename(filename, "-tests.ts"), [filename], paramFile);
117+
});
118+
}
119+
});
120+
})
121+
});
122+
}
123+
124+
importDefinitelyTypedTests(definitelyTypedRoot);

src/compiler/checker.ts

Lines changed: 96 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4523,25 +4523,26 @@ module ts {
45234523
}
45244524
}
45254525
}
4526+
checkSignatureDeclaration(node);
45264527
}
45274528
}
4528-
if (fullTypeCheck && !(links.flags & NodeCheckFlags.TypeChecked)) {
4529-
checkSignatureDeclaration(node);
4529+
return type;
4530+
}
4531+
4532+
function checkFunctionExpressionBody(node: FunctionExpression) {
4533+
if (node.type) {
4534+
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type));
4535+
}
4536+
if (node.body.kind === SyntaxKind.FunctionBlock) {
4537+
checkSourceElement(node.body);
4538+
}
4539+
else {
4540+
var exprType = checkExpression(node.body);
45304541
if (node.type) {
4531-
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type));
4532-
}
4533-
if (node.body.kind === SyntaxKind.FunctionBlock) {
4534-
checkSourceElement(node.body);
4542+
checkTypeAssignableTo(exprType, getTypeFromTypeNode(node.type), node.body, undefined, undefined);
45354543
}
4536-
else {
4537-
var exprType = checkExpression(node.body);
4538-
if (node.type) {
4539-
checkTypeAssignableTo(exprType, getTypeFromTypeNode(node.type), node.body, undefined, undefined);
4540-
}
4541-
}
4542-
links.flags |= NodeCheckFlags.TypeChecked;
4544+
checkFunctionExpressionBodies(node.body);
45434545
}
4544-
return type;
45454546
}
45464547

45474548
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
@@ -6437,9 +6438,10 @@ module ts {
64376438
case SyntaxKind.FunctionDeclaration:
64386439
return checkFunctionDeclaration(<FunctionDeclaration>node);
64396440
case SyntaxKind.Block:
6441+
return checkBlock(<Block>node);
64406442
case SyntaxKind.FunctionBlock:
64416443
case SyntaxKind.ModuleBlock:
6442-
return checkBlock(<Block>node);
6444+
return checkBody(<Block>node);
64436445
case SyntaxKind.VariableStatement:
64446446
return checkVariableStatement(<VariableStatement>node);
64456447
case SyntaxKind.ExpressionStatement:
@@ -6486,13 +6488,91 @@ module ts {
64866488
}
64876489
}
64886490

6491+
// Function expression bodies are checked after all statements in the enclosing body. This is to ensure
6492+
// constructs like the following are permitted:
6493+
// var foo = function () {
6494+
// var s = foo();
6495+
// return "hello";
6496+
// }
6497+
// Here, performing a full type check of the body of the function expression whilst in the process of
6498+
// determining the type of foo would cause foo to be given type any because of the recursive reference.
6499+
// Delaying the type check of the body ensures foo has been assigned a type.
6500+
function checkFunctionExpressionBodies(node: Node): void {
6501+
switch (node.kind) {
6502+
case SyntaxKind.FunctionExpression:
6503+
case SyntaxKind.ArrowFunction:
6504+
forEach((<FunctionDeclaration>node).parameters, checkFunctionExpressionBodies);
6505+
checkFunctionExpressionBody(<FunctionExpression>node);
6506+
break;
6507+
case SyntaxKind.Method:
6508+
case SyntaxKind.Constructor:
6509+
case SyntaxKind.GetAccessor:
6510+
case SyntaxKind.SetAccessor:
6511+
case SyntaxKind.FunctionDeclaration:
6512+
forEach((<FunctionDeclaration>node).parameters, checkFunctionExpressionBodies);
6513+
break;
6514+
case SyntaxKind.WithStatement:
6515+
checkFunctionExpressionBodies((<WithStatement>node).expression);
6516+
break;
6517+
case SyntaxKind.Parameter:
6518+
case SyntaxKind.Property:
6519+
case SyntaxKind.ArrayLiteral:
6520+
case SyntaxKind.ObjectLiteral:
6521+
case SyntaxKind.PropertyAssignment:
6522+
case SyntaxKind.PropertyAccess:
6523+
case SyntaxKind.IndexedAccess:
6524+
case SyntaxKind.CallExpression:
6525+
case SyntaxKind.NewExpression:
6526+
case SyntaxKind.TypeAssertion:
6527+
case SyntaxKind.ParenExpression:
6528+
case SyntaxKind.PrefixOperator:
6529+
case SyntaxKind.PostfixOperator:
6530+
case SyntaxKind.BinaryExpression:
6531+
case SyntaxKind.ConditionalExpression:
6532+
case SyntaxKind.Block:
6533+
case SyntaxKind.FunctionBlock:
6534+
case SyntaxKind.ModuleBlock:
6535+
case SyntaxKind.VariableStatement:
6536+
case SyntaxKind.ExpressionStatement:
6537+
case SyntaxKind.IfStatement:
6538+
case SyntaxKind.DoStatement:
6539+
case SyntaxKind.WhileStatement:
6540+
case SyntaxKind.ForStatement:
6541+
case SyntaxKind.ForInStatement:
6542+
case SyntaxKind.ContinueStatement:
6543+
case SyntaxKind.BreakStatement:
6544+
case SyntaxKind.ReturnStatement:
6545+
case SyntaxKind.SwitchStatement:
6546+
case SyntaxKind.CaseClause:
6547+
case SyntaxKind.DefaultClause:
6548+
case SyntaxKind.LabelledStatement:
6549+
case SyntaxKind.ThrowStatement:
6550+
case SyntaxKind.TryStatement:
6551+
case SyntaxKind.TryBlock:
6552+
case SyntaxKind.CatchBlock:
6553+
case SyntaxKind.FinallyBlock:
6554+
case SyntaxKind.VariableDeclaration:
6555+
case SyntaxKind.ClassDeclaration:
6556+
case SyntaxKind.EnumDeclaration:
6557+
case SyntaxKind.EnumMember:
6558+
case SyntaxKind.SourceFile:
6559+
forEachChild(node, checkFunctionExpressionBodies);
6560+
break;
6561+
}
6562+
}
6563+
6564+
function checkBody(node: Block) {
6565+
checkBlock(node);
6566+
checkFunctionExpressionBodies(node);
6567+
}
6568+
64896569
// Fully type check a source file and collect the relevant diagnostics.
64906570
function checkSourceFile(node: SourceFile) {
64916571
var links = getNodeLinks(node);
64926572
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
64936573
emitExtends = false;
64946574
potentialThisCollisions.length = 0;
6495-
forEach(node.statements, checkSourceElement);
6575+
checkBody(node);
64966576
if (isExternalModule(node)) {
64976577
var symbol = getExportAssignmentSymbol(node.symbol);
64986578
if (symbol && symbol.flags & SymbolFlags.Import) {

src/compiler/emitter.ts

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,9 +3080,7 @@ module ts {
30803080
}
30813081

30823082
function resolveScriptReference(sourceFile: SourceFile, reference: FileReference) {
3083-
var referenceFileName = compilerOptions.noResolve
3084-
? reference.filename
3085-
: normalizePath(combinePaths(getDirectoryPath(sourceFile.filename), reference.filename));
3083+
var referenceFileName = normalizePath(combinePaths(getDirectoryPath(sourceFile.filename), reference.filename));
30863084
return program.getSourceFile(referenceFileName);
30873085
}
30883086

@@ -3103,26 +3101,28 @@ module ts {
31033101
compilerHost.getCurrentDirectory(),
31043102
/*isAbsolutePathAnUrl*/ false);
31053103

3106-
referencePathsOutput += "/// <reference path='" + declFileName + "' />" + newLine;
3104+
referencePathsOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
31073105
}
31083106

31093107
if (root) {
31103108
// Emiting single file so emit references in this file only
3111-
var addedGlobalFileReference = false;
3112-
forEach(root.referencedFiles, fileReference => {
3113-
var referencedFile = resolveScriptReference(root, fileReference);
3114-
3115-
// All the references that are not going to be part of same file
3116-
if ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
3117-
shouldEmitToOwnFile(referencedFile) || // This is referenced file is emitting its own js file
3118-
!addedGlobalFileReference) { // Or the global out file corresponding to this reference was not added
3119-
3120-
writeReferencePath(referencedFile);
3121-
if (!isExternalModuleOrDeclarationFile(referencedFile)) {
3122-
addedGlobalFileReference = true;
3109+
if (!compilerOptions.noResolve) {
3110+
var addedGlobalFileReference = false;
3111+
forEach(root.referencedFiles, fileReference => {
3112+
var referencedFile = resolveScriptReference(root, fileReference);
3113+
3114+
// All the references that are not going to be part of same file
3115+
if ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
3116+
shouldEmitToOwnFile(referencedFile) || // This is referenced file is emitting its own js file
3117+
!addedGlobalFileReference) { // Or the global out file corresponding to this reference was not added
3118+
3119+
writeReferencePath(referencedFile);
3120+
if (!isExternalModuleOrDeclarationFile(referencedFile)) {
3121+
addedGlobalFileReference = true;
3122+
}
31233123
}
3124-
}
3125-
});
3124+
});
3125+
}
31263126

31273127
emitNode(root);
31283128
}
@@ -3132,17 +3132,19 @@ module ts {
31323132
forEach(program.getSourceFiles(), sourceFile => {
31333133
if (!isExternalModuleOrDeclarationFile(sourceFile)) {
31343134
// Check what references need to be added
3135-
forEach(sourceFile.referencedFiles, fileReference => {
3136-
var referencedFile = resolveScriptReference(sourceFile, fileReference);
3135+
if (!compilerOptions.noResolve) {
3136+
forEach(sourceFile.referencedFiles, fileReference => {
3137+
var referencedFile = resolveScriptReference(sourceFile, fileReference);
31373138

3138-
// If the reference file is declaration file or external module emit that reference
3139-
if (isExternalModuleOrDeclarationFile(referencedFile) &&
3140-
!contains(emittedReferencedFiles, referencedFile)) { // If the file refernece was not already emitted
3139+
// If the reference file is declaration file or external module emit that reference
3140+
if (isExternalModuleOrDeclarationFile(referencedFile) &&
3141+
!contains(emittedReferencedFiles, referencedFile)) { // If the file refernece was not already emitted
31413142

3142-
writeReferencePath(referencedFile);
3143-
emittedReferencedFiles.push(referencedFile);
3144-
}
3145-
});
3143+
writeReferencePath(referencedFile);
3144+
emittedReferencedFiles.push(referencedFile);
3145+
}
3146+
});
3147+
}
31463148

31473149
emitNode(sourceFile);
31483150
}

tests/baselines/reference/declFileAmbientExternalModuleWithSingleExportedModule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ declare module "SubModule" {
3333
}
3434
}
3535
//// [declFileAmbientExternalModuleWithSingleExportedModule_1.d.ts]
36-
/// <reference path='declFileAmbientExternalModuleWithSingleExportedModule_0.d.ts' />
36+
/// <reference path="declFileAmbientExternalModuleWithSingleExportedModule_0.d.ts" />
3737
import SubModule = require('SubModule');
3838
export declare var x: SubModule.m.m3.c;

tests/baselines/reference/declFileForExportedImport.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ var z = exports.b.x;
2424
//// [declFileForExportedImport_0.d.ts]
2525
export declare var x: number;
2626
//// [declFileForExportedImport_1.d.ts]
27-
/// <reference path='declFileForExportedImport_0.d.ts' />
27+
/// <reference path="declFileForExportedImport_0.d.ts" />
2828
export import a = require('declFileForExportedImport_0');
2929
export import b = a;

tests/baselines/reference/declFileTypeofFunction.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,6 @@ declare function b1(): typeof b1;
7373
declare function foo(): typeof foo;
7474
declare var foo1: typeof foo;
7575
declare var foo2: typeof foo;
76-
declare var foo3: any;
77-
declare var x: any;
76+
declare var foo3: () => any;
77+
declare var x: () => any;
7878
declare function foo5(x: number): (x: number) => number;

0 commit comments

Comments
 (0)