Skip to content

Commit b580c55

Browse files
committed
Merge branch 'master' into tscJsFiles
2 parents 756052a + 53cff21 commit b580c55

File tree

527 files changed

+9930
-4549
lines changed

Some content is hidden

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

527 files changed

+9930
-4549
lines changed

.gitignore

+3-2
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,6 @@ scripts/typings/
4040
coverage/
4141
internal/
4242
**/.DS_Store
43-
.settings/*
44-
!.settings/tasks.json
43+
.settings
44+
.vscode/*
45+
!.vscode/tasks.json

.npmignore

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ doc
33
scripts
44
src
55
tests
6-
Jakefile
6+
internal
7+
tslint.json
8+
Jakefile.js
9+
.editorconfig
10+
.gitattributes
11+
.settings/
712
.travis.yml
8-
.settings/
13+
.vscode/

.vscode/tasks.json

+19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@
1818
"problemMatcher": [
1919
"$tsc"
2020
]
21+
},
22+
{
23+
"taskName": "lint-server",
24+
"args": [],
25+
"problemMatcher": {
26+
"owner": "typescript",
27+
"fileLocation": ["relative", "${workspaceRoot}"],
28+
"pattern": {
29+
"regexp": "^(warning|error)\\s+([^(]+)\\s+\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(.*)$",
30+
"severity": 1,
31+
"file": 2,
32+
"location": 3,
33+
"message": 4
34+
},
35+
"watchedTaskBeginsRegExp": "^\\*\\*\\*Lint failure\\*\\*\\*$",
36+
"watchedTaskEndsRegExp": "^\\*\\*\\* Total \\d+ failures\\.$"
37+
},
38+
"showOutput": "always",
39+
"isWatching": true
2140
}
2241
]
2342
}

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Design changes will not be accepted at this time. If you have a design change pr
99
## Legal
1010
You will need to complete a Contributor License Agreement (CLA). Briefly, this agreement testifies that you are granting us permission to use the submitted change according to the terms of the project's license, and that the work being submitted is under appropriate copyright.
1111

12-
Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement ([Microsoft Contribution License Agreement.docx](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=822190) or [Microsoft Contribution License Agreement.pdf](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=921298)), sign, scan, and email it back to <cla@microsoft.com>. Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request. Please note that we're currently only accepting pull requests of bug fixes rather than new features.
12+
Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement ([Microsoft Contribution License Agreement.docx](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=822190) or [Microsoft Contribution License Agreement.pdf](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=921298)), sign, scan, and email it back to <cla@microsoft.com>. Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request.
1313

1414
## Housekeeping
1515
Your pull request should:

Jakefile.js

+96-16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var fs = require("fs");
44
var os = require("os");
55
var path = require("path");
66
var child_process = require("child_process");
7+
var Linter = require("tslint");
78

89
// Variables
910
var compilerDirectory = "src/compiler/";
@@ -627,10 +628,9 @@ function deleteTemporaryProjectOutput() {
627628

628629
var testTimeout = 20000;
629630
desc("Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|<more>]', debug=true.");
630-
task("runtests", ["tests", builtLocalDirectory], function() {
631+
task("runtests", ["build-rules", "tests", builtLocalDirectory], function() {
631632
cleanTestDirs();
632633
var debug = process.env.debug || process.env.d;
633-
host = "mocha"
634634
tests = process.env.test || process.env.tests || process.env.t;
635635
var light = process.env.light || false;
636636
var testConfigFile = 'test.config';
@@ -652,9 +652,16 @@ task("runtests", ["tests", builtLocalDirectory], function() {
652652
reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter';
653653
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
654654
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
655-
var cmd = host + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run;
655+
var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run;
656656
console.log(cmd);
657-
exec(cmd, deleteTemporaryProjectOutput);
657+
exec(cmd, function() {
658+
deleteTemporaryProjectOutput();
659+
var lint = jake.Task['lint'];
660+
lint.addListener('complete', function () {
661+
complete();
662+
});
663+
lint.invoke();
664+
});
658665
}, {async: true});
659666

660667
desc("Generates code coverage data via instanbul");
@@ -812,7 +819,6 @@ task("update-sublime", ["local", serverFile], function() {
812819
var tslintRuleDir = "scripts/tslint";
813820
var tslintRules = ([
814821
"nextLineRule",
815-
"noInferrableTypesRule",
816822
"noNullRule",
817823
"booleanTriviaRule"
818824
]);
@@ -825,20 +831,94 @@ var tslintRulesOutFiles = tslintRules.map(function(p) {
825831
desc("Compiles tslint rules to js");
826832
task("build-rules", tslintRulesOutFiles);
827833
tslintRulesFiles.forEach(function(ruleFile, i) {
828-
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ true, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
834+
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
829835
});
830836

831-
// if the codebase were free of linter errors we could make jake runtests
832-
// run this task automatically
837+
function getLinterOptions() {
838+
return {
839+
configuration: require("./tslint.json"),
840+
formatter: "prose",
841+
formattersDirectory: undefined,
842+
rulesDirectory: "built/local/tslint"
843+
};
844+
}
845+
846+
function lintFileContents(options, path, contents) {
847+
var ll = new Linter(path, contents, options);
848+
return ll.lint();
849+
}
850+
851+
function lintFile(options, path) {
852+
var contents = fs.readFileSync(path, "utf8");
853+
return lintFileContents(options, path, contents);
854+
}
855+
856+
function lintFileAsync(options, path, cb) {
857+
fs.readFile(path, "utf8", function(err, contents) {
858+
if (err) {
859+
return cb(err);
860+
}
861+
var result = lintFileContents(options, path, contents);
862+
cb(undefined, result);
863+
});
864+
}
865+
866+
var lintTargets = compilerSources.concat(harnessCoreSources);
867+
833868
desc("Runs tslint on the compiler sources");
834869
task("lint", ["build-rules"], function() {
835-
function success(f) { return function() { console.log('SUCCESS: No linter errors in ' + f + '\n'); }};
836-
function failure(f) { return function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n') }};
837-
838-
var lintTargets = compilerSources.concat(harnessCoreSources);
870+
var lintOptions = getLinterOptions();
839871
for (var i in lintTargets) {
840-
var f = lintTargets[i];
841-
var cmd = 'tslint --rules-dir built/local/tslint -c tslint.json ' + f;
842-
exec(cmd, success(f), failure(f));
872+
var result = lintFile(lintOptions, lintTargets[i]);
873+
if (result.failureCount > 0) {
874+
console.log(result.output);
875+
fail('Linter errors.', result.failureCount);
876+
}
843877
}
844-
}, { async: true });
878+
});
879+
880+
/**
881+
* This is required because file watches on Windows get fires _twice_
882+
* when a file changes on some node/windows version configuations
883+
* (node v4 and win 10, for example). By not running a lint for a file
884+
* which already has a pending lint, we avoid duplicating our work.
885+
* (And avoid printing duplicate results!)
886+
*/
887+
var lintSemaphores = {};
888+
889+
function lintWatchFile(filename) {
890+
fs.watch(filename, {persistent: true}, function(event) {
891+
if (event !== "change") {
892+
return;
893+
}
894+
895+
if (!lintSemaphores[filename]) {
896+
lintSemaphores[filename] = true;
897+
lintFileAsync(getLinterOptions(), filename, function(err, result) {
898+
delete lintSemaphores[filename];
899+
if (err) {
900+
console.log(err);
901+
return;
902+
}
903+
if (result.failureCount > 0) {
904+
console.log("***Lint failure***");
905+
for (var i = 0; i < result.failures.length; i++) {
906+
var failure = result.failures[i];
907+
var start = failure.startPosition.lineAndCharacter;
908+
var end = failure.endPosition.lineAndCharacter;
909+
console.log("warning " + filename + " (" + (start.line + 1) + "," + (start.character + 1) + "," + (end.line + 1) + "," + (end.character + 1) + "): " + failure.failure);
910+
}
911+
console.log("*** Total " + result.failureCount + " failures.");
912+
}
913+
});
914+
}
915+
});
916+
}
917+
918+
desc("Watches files for changes to rerun a lint pass");
919+
task("lint-server", ["build-rules"], function() {
920+
console.log("Watching ./src for changes to linted files");
921+
for (var i = 0; i < lintTargets.length; i++) {
922+
lintWatchFile(lintTargets[i]);
923+
}
924+
});

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@
4444
"build": "npm run build:compiler && npm run build:tests",
4545
"build:compiler": "jake local",
4646
"build:tests": "jake tests",
47-
"clean": "jake clean"
47+
"clean": "jake clean",
48+
"jake": "jake",
49+
"lint": "jake lint",
50+
"setup-hooks": "node scripts/link-hooks.js"
4851
},
4952
"browser": {
5053
"buffer": false,

scripts/hooks/post-checkout

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
npm run jake -- generate-diagnostics

scripts/link-hooks.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var fs = require("fs");
2+
var path = require("path");
3+
4+
var hooks = [
5+
"post-checkout"
6+
];
7+
8+
hooks.forEach(function (hook) {
9+
var hookInSourceControl = path.resolve(__dirname, "hooks", hook);
10+
11+
if (fs.existsSync(hookInSourceControl)) {
12+
var hookInHiddenDirectory = path.resolve(__dirname, "..", ".git", "hooks", hook);
13+
14+
if (fs.existsSync(hookInHiddenDirectory)) {
15+
fs.unlinkSync(hookInHiddenDirectory);
16+
}
17+
18+
fs.linkSync(hookInSourceControl, hookInHiddenDirectory);
19+
}
20+
});

scripts/tslint/nextLineRule.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ const OPTION_CATCH = "check-catch";
55
const OPTION_ELSE = "check-else";
66

77
export class Rule extends Lint.Rules.AbstractRule {
8-
public static CATCH_FAILURE_STRING = "'catch' should be on the line following the previous block's ending curly brace";
9-
public static ELSE_FAILURE_STRING = "'else' should be on the line following the previous block's ending curly brace";
8+
public static CATCH_FAILURE_STRING = "'catch' should not be on the same line as the preceeding block's curly brace";
9+
public static ELSE_FAILURE_STRING = "'else' should not be on the same line as the preceeding block's curly brace";
1010

1111
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
1212
return this.applyWithWalker(new NextLineWalker(sourceFile, this.getOptions()));
@@ -25,7 +25,7 @@ class NextLineWalker extends Lint.RuleWalker {
2525
if (this.hasOption(OPTION_ELSE) && !!elseKeyword) {
2626
const thenStatementEndLoc = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd());
2727
const elseKeywordLoc = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart(sourceFile));
28-
if (thenStatementEndLoc.line !== (elseKeywordLoc.line - 1)) {
28+
if (thenStatementEndLoc.line === elseKeywordLoc.line) {
2929
const failure = this.createFailure(elseKeyword.getStart(sourceFile), elseKeyword.getWidth(sourceFile), Rule.ELSE_FAILURE_STRING);
3030
this.addFailure(failure);
3131
}
@@ -47,7 +47,7 @@ class NextLineWalker extends Lint.RuleWalker {
4747
const catchKeyword = catchClause.getFirstToken(sourceFile);
4848
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
4949
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
50-
if (tryClosingBraceLoc.line !== (catchKeywordLoc.line - 1)) {
50+
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {
5151
const failure = this.createFailure(catchKeyword.getStart(sourceFile), catchKeyword.getWidth(sourceFile), Rule.CATCH_FAILURE_STRING);
5252
this.addFailure(failure);
5353
}
@@ -58,4 +58,4 @@ class NextLineWalker extends Lint.RuleWalker {
5858

5959
function getFirstChildOfKind(node: ts.Node, kind: ts.SyntaxKind) {
6060
return node.getChildren().filter((child) => child.kind === kind)[0];
61-
}
61+
}

scripts/tslint/noInferrableTypesRule.ts

-49
This file was deleted.

src/compiler/binder.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ namespace ts {
8888
let container: Node;
8989
let blockScopeContainer: Node;
9090
let lastContainer: Node;
91+
let seenThisKeyword: boolean;
9192

9293
// If this file is an external module, then it is automatically in strict-mode according to
9394
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
@@ -329,7 +330,14 @@ namespace ts {
329330
blockScopeContainer.locals = undefined;
330331
}
331332

332-
forEachChild(node, bind);
333+
if (node.kind === SyntaxKind.InterfaceDeclaration) {
334+
seenThisKeyword = false;
335+
forEachChild(node, bind);
336+
node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis;
337+
}
338+
else {
339+
forEachChild(node, bind);
340+
}
333341

334342
container = saveContainer;
335343
parent = saveParent;
@@ -851,6 +859,9 @@ namespace ts {
851859
return checkStrictModePrefixUnaryExpression(<PrefixUnaryExpression>node);
852860
case SyntaxKind.WithStatement:
853861
return checkStrictModeWithStatement(<WithStatement>node);
862+
case SyntaxKind.ThisKeyword:
863+
seenThisKeyword = true;
864+
return;
854865

855866
case SyntaxKind.TypeParameter:
856867
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);

0 commit comments

Comments
 (0)