Skip to content

Commit 5a65e08

Browse files
committed
Merge remote-tracking branch 'microsoft/master' into better-type-as-value-error
# Conflicts: # src/compiler/diagnosticMessages.json
2 parents 5762519 + d8ab098 commit 5a65e08

File tree

165 files changed

+4745
-1505
lines changed

Some content is hidden

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

165 files changed

+4745
-1505
lines changed

Gulpfile.ts

Lines changed: 119 additions & 95 deletions
Large diffs are not rendered by default.

Jakefile.js

Lines changed: 222 additions & 238 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
[![Join the chat at https://gitter.im/Microsoft/TypeScript](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
88

9-
[TypeScript](http://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](http://www.typescriptlang.org/Playground), and stay up to date via [our blog](http://blogs.msdn.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
9+
[TypeScript](http://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](http://www.typescriptlang.org/Playground), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
1010

1111
## Installing
1212

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"mkdirp": "latest",
7070
"mocha": "latest",
7171
"mocha-fivemat-progress-reporter": "latest",
72+
"q": "latest",
7273
"run-sequence": "latest",
7374
"sorcery": "latest",
7475
"through2": "latest",

scripts/ior.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/// <reference path="../src/harness/external/node.d.ts" />
1+
/// <reference types="node"/>
22

33
import fs = require('fs');
44
import path = require('path');

scripts/parallel-lint.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
var Linter = require("tslint");
2+
var fs = require("fs");
3+
4+
function getLinterOptions() {
5+
return {
6+
configuration: require("../tslint.json"),
7+
formatter: "prose",
8+
formattersDirectory: undefined,
9+
rulesDirectory: "built/local/tslint"
10+
};
11+
}
12+
13+
function lintFileContents(options, path, contents) {
14+
var ll = new Linter(path, contents, options);
15+
return ll.lint();
16+
}
17+
18+
function lintFileAsync(options, path, cb) {
19+
fs.readFile(path, "utf8", function (err, contents) {
20+
if (err) {
21+
return cb(err);
22+
}
23+
var result = lintFileContents(options, path, contents);
24+
cb(undefined, result);
25+
});
26+
}
27+
28+
process.on("message", function (data) {
29+
switch (data.kind) {
30+
case "file":
31+
var target = data.name;
32+
var lintOptions = getLinterOptions();
33+
lintFileAsync(lintOptions, target, function (err, result) {
34+
if (err) {
35+
process.send({ kind: "error", error: err.toString() });
36+
return;
37+
}
38+
process.send({ kind: "result", failures: result.failureCount, output: result.output });
39+
});
40+
break;
41+
case "close":
42+
process.exit(0);
43+
break;
44+
}
45+
});

scripts/types/ambient.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare module "gulp-insert" {
1010
export function append(text: string | Buffer): NodeJS.ReadWriteStream;
1111
export function prepend(text: string | Buffer): NodeJS.ReadWriteStream;
1212
export function wrap(text: string | Buffer, tail: string | Buffer): NodeJS.ReadWriteStream;
13-
export function transform(cb: (contents: string, file: {path: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file
13+
export function transform(cb: (contents: string, file: {path: string, relative: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file
1414
}
1515

1616
declare module "into-stream" {

src/compiler/binder.ts

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ namespace ts {
8989
const binder = createBinder();
9090

9191
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
92-
const start = performance.mark();
92+
performance.mark("beforeBind");
9393
binder(file, options);
94-
performance.measure("Bind", start);
94+
performance.mark("afterBind");
95+
performance.measure("Bind", "beforeBind", "afterBind");
9596
}
9697

9798
function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
@@ -298,8 +299,10 @@ namespace ts {
298299
const name = isDefaultExport && parent ? "default" : getDeclarationName(node);
299300

300301
let symbol: Symbol;
301-
if (name !== undefined) {
302-
302+
if (name === undefined) {
303+
symbol = createSymbol(SymbolFlags.None, "__missing");
304+
}
305+
else {
303306
// Check and see if the symbol table already has a symbol with this name. If not,
304307
// create a new symbol with this name and add it to the table. Note that we don't
305308
// give the new symbol any flags *yet*. This ensures that it will not conflict
@@ -311,6 +314,11 @@ namespace ts {
311314
// declaration we have for this symbol, and then create a new symbol for this
312315
// declaration.
313316
//
317+
// Note that when properties declared in Javascript constructors
318+
// (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
319+
// Always. This allows the common Javascript pattern of overwriting a prototype method
320+
// with an bound instance method of the same type: `this.method = this.method.bind(this)`
321+
//
314322
// If we created a new symbol, either because we didn't have a symbol with this name
315323
// in the symbol table, or we conflicted with an existing symbol, then just add this
316324
// node as the sole declaration of the new symbol.
@@ -325,33 +333,37 @@ namespace ts {
325333
}
326334

327335
if (symbol.flags & excludes) {
328-
if (node.name) {
329-
node.name.parent = node;
336+
if (symbol.isReplaceableByMethod) {
337+
// Javascript constructor-declared symbols can be discarded in favor of
338+
// prototype symbols like methods.
339+
symbol = symbolTable[name] = createSymbol(SymbolFlags.None, name);
330340
}
341+
else {
342+
if (node.name) {
343+
node.name.parent = node;
344+
}
331345

332-
// Report errors every position with duplicate declaration
333-
// Report errors on previous encountered declarations
334-
let message = symbol.flags & SymbolFlags.BlockScopedVariable
335-
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
336-
: Diagnostics.Duplicate_identifier_0;
346+
// Report errors every position with duplicate declaration
347+
// Report errors on previous encountered declarations
348+
let message = symbol.flags & SymbolFlags.BlockScopedVariable
349+
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
350+
: Diagnostics.Duplicate_identifier_0;
337351

338-
forEach(symbol.declarations, declaration => {
339-
if (declaration.flags & NodeFlags.Default) {
340-
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
341-
}
342-
});
352+
forEach(symbol.declarations, declaration => {
353+
if (declaration.flags & NodeFlags.Default) {
354+
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
355+
}
356+
});
343357

344-
forEach(symbol.declarations, declaration => {
345-
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
346-
});
347-
file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
358+
forEach(symbol.declarations, declaration => {
359+
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
360+
});
361+
file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
348362

349-
symbol = createSymbol(SymbolFlags.None, name);
363+
symbol = createSymbol(SymbolFlags.None, name);
364+
}
350365
}
351366
}
352-
else {
353-
symbol = createSymbol(SymbolFlags.None, "__missing");
354-
}
355367

356368
addDeclarationToSymbol(symbol, node, includes);
357369
symbol.parent = parent;
@@ -1965,20 +1977,25 @@ namespace ts {
19651977
}
19661978

19671979
function bindThisPropertyAssignment(node: BinaryExpression) {
1968-
// Declare a 'member' in case it turns out the container was an ES5 class or ES6 constructor
1969-
let assignee: Node;
1980+
Debug.assert(isInJavaScriptFile(node));
1981+
// Declare a 'member' if the container is an ES5 class or ES6 constructor
19701982
if (container.kind === SyntaxKind.FunctionDeclaration || container.kind === SyntaxKind.FunctionExpression) {
1971-
assignee = container;
1983+
container.symbol.members = container.symbol.members || createMap<Symbol>();
1984+
// It's acceptable for multiple 'this' assignments of the same identifier to occur
1985+
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
19721986
}
19731987
else if (container.kind === SyntaxKind.Constructor) {
1974-
assignee = container.parent;
1975-
}
1976-
else {
1977-
return;
1988+
// this.foo assignment in a JavaScript class
1989+
// Bind this property to the containing class
1990+
const saveContainer = container;
1991+
container = container.parent;
1992+
const symbol = bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.None);
1993+
if (symbol) {
1994+
// constructor-declared symbols can be overwritten by subsequent method declarations
1995+
(symbol as Symbol).isReplaceableByMethod = true;
1996+
}
1997+
container = saveContainer;
19781998
}
1979-
assignee.symbol.members = assignee.symbol.members || createMap<Symbol>();
1980-
// It's acceptable for multiple 'this' assignments of the same identifier to occur
1981-
declareSymbol(assignee.symbol.members, assignee.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
19821999
}
19832000

19842001
function bindPrototypePropertyAssignment(node: BinaryExpression) {

0 commit comments

Comments
 (0)