Skip to content

Commit 271ffc8

Browse files
committed
Merge branch 'master' into instantiate-this-for-contextually-typed-type-parameters
2 parents 78f807c + 0006371 commit 271ffc8

File tree

900 files changed

+27413
-35439
lines changed

Some content is hidden

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

900 files changed

+27413
-35439
lines changed

.travis.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,34 @@ node_js:
66
- '0.10'
77

88
sudo: false
9+
10+
env:
11+
- workerCount=3
12+
13+
matrix:
14+
fast_finish: true
15+
include:
16+
- os: osx
17+
node_js: stable
18+
osx_image: xcode7.3
19+
env: workerCount=2
20+
allow_failures:
21+
- os: osx
22+
23+
branches:
24+
only:
25+
- master
26+
- transforms
27+
28+
install:
29+
- npm uninstall typescript
30+
- npm uninstall tslint
31+
- npm install
32+
- npm update
33+
34+
cache:
35+
directories:
36+
- node_modules
37+
38+
git:
39+
depth: 1

Gulpfile.ts

Lines changed: 110 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import through2 = require("through2");
3434
import merge2 = require("merge2");
3535
import intoStream = require("into-stream");
3636
import * as os from "os";
37-
import Linter = require("tslint");
37+
import fold = require("travis-fold");
3838
const gulp = helpMaker(originalGulp);
3939
const mochaParallel = require("./scripts/mocha-parallel.js");
4040
const {runTestsInParallel} = mochaParallel;
@@ -59,7 +59,6 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
5959
browser: process.env.browser || process.env.b || "IE",
6060
tests: process.env.test || process.env.tests || process.env.t,
6161
light: process.env.light || false,
62-
port: process.env.port || process.env.p || "8888",
6362
reporter: process.env.reporter || process.env.r,
6463
lint: process.env.lint || true,
6564
files: process.env.f || process.env.file || process.env.files || "",
@@ -450,7 +449,7 @@ gulp.task(tsserverLibraryFile, false, [servicesFile], (done) => {
450449
});
451450

452451
gulp.task("lssl", "Builds language service server library", [tsserverLibraryFile]);
453-
gulp.task("local", "Builds the full compiler and services", [builtLocalCompiler, servicesFile, serverFile, builtGeneratedDiagnosticMessagesJSON]);
452+
gulp.task("local", "Builds the full compiler and services", [builtLocalCompiler, servicesFile, serverFile, builtGeneratedDiagnosticMessagesJSON, tsserverLibraryFile]);
454453
gulp.task("tsc", "Builds only the compiler", [builtLocalCompiler]);
455454

456455

@@ -504,7 +503,7 @@ gulp.task("VerifyLKG", false, [], () => {
504503
return gulp.src(expectedFiles).pipe(gulp.dest(LKGDirectory));
505504
});
506505

507-
gulp.task("LKGInternal", false, ["lib", "local", "lssl"]);
506+
gulp.task("LKGInternal", false, ["lib", "local"]);
508507

509508
gulp.task("LKG", "Makes a new LKG out of the built js files", ["clean", "dontUseDebugMode"], () => {
510509
return runSequence("LKGInternal", "VerifyLKG");
@@ -694,21 +693,50 @@ gulp.task(nodeServerOutFile, false, [servicesFile], () => {
694693
.pipe(gulp.dest(path.dirname(nodeServerOutFile)));
695694
});
696695

696+
import convertMap = require("convert-source-map");
697+
import sorcery = require("sorcery");
698+
declare module "convert-source-map" {
699+
export function fromSource(source: string, largeSource?: boolean): SourceMapConverter;
700+
}
701+
697702
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
698703
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "built/local/bundle.js" }, /*useBuiltCompiler*/ true));
699704
return testProject.src()
700705
.pipe(newer("built/local/bundle.js"))
701706
.pipe(sourcemaps.init())
702707
.pipe(tsc(testProject))
703708
.pipe(through2.obj((file, enc, next) => {
704-
browserify(intoStream(file.contents))
709+
const originalMap = file.sourceMap;
710+
const prebundledContent = file.contents.toString();
711+
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
712+
originalMap.sources = originalMap.sources.map(s => path.resolve("src", s));
713+
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
714+
originalMap.file = "built/local/_stream_0.js";
715+
716+
browserify(intoStream(file.contents), { debug: true })
705717
.bundle((err, res) => {
706718
// assumes file.contents is a Buffer
707-
file.contents = res;
719+
const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/true).toJSON());
720+
delete maps.sourceRoot;
721+
maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s));
722+
// Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths)
723+
file.contents = new Buffer(convertMap.removeComments(res.toString()));
724+
const chain = sorcery.loadSync("built/local/bundle.js", {
725+
content: {
726+
"built/local/_stream_0.js": prebundledContent,
727+
"built/local/bundle.js": file.contents.toString()
728+
},
729+
sourcemaps: {
730+
"built/local/_stream_0.js": originalMap,
731+
"built/local/bundle.js": maps,
732+
}
733+
});
734+
const finalMap = chain.apply();
735+
file.sourceMap = finalMap;
708736
next(undefined, file);
709737
});
710738
}))
711-
.pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "../../" }))
739+
.pipe(sourcemaps.write(".", { includeContent: false }))
712740
.pipe(gulp.dest("."));
713741
});
714742

@@ -737,7 +765,7 @@ function writeTestConfigFile(tests: string, light: boolean, taskConfigsFolder?:
737765
}
738766

739767

740-
gulp.task("runtests-browser", "Runs the tests using the built run.js file like 'gulp runtests'. Syntax is gulp runtests-browser. Additional optional parameters --tests=[regex], --port=, --browser=[chrome|IE]", ["browserify", nodeServerOutFile], (done) => {
768+
gulp.task("runtests-browser", "Runs the tests using the built run.js file like 'gulp runtests'. Syntax is gulp runtests-browser. Additional optional parameters --tests=[regex], --browser=[chrome|IE]", ["browserify", nodeServerOutFile], (done) => {
741769
cleanTestDirs((err) => {
742770
if (err) { console.error(err); done(err); process.exit(1); }
743771
host = "node";
@@ -752,9 +780,6 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like '
752780
}
753781

754782
const args = [nodeServerOutFile];
755-
if (cmdLineOptions["port"]) {
756-
args.push(cmdLineOptions["port"]);
757-
}
758783
if (cmdLineOptions["browser"]) {
759784
args.push(cmdLineOptions["browser"]);
760785
}
@@ -889,57 +914,20 @@ gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", s
889914
return gulp.src([serverFile, serverFile + ".map"]).pipe(gulp.dest("../TypeScript-Sublime-Plugin/tsserver/"));
890915
});
891916

892-
893-
const tslintRuleDir = "scripts/tslint";
894-
const tslintRules = [
895-
"nextLineRule",
896-
"preferConstRule",
897-
"booleanTriviaRule",
898-
"typeOperatorSpacingRule",
899-
"noInOperatorRule",
900-
"noIncrementDecrementRule",
901-
"objectLiteralSurroundingSpaceRule",
902-
];
903-
const tslintRulesFiles = tslintRules.map(function(p) {
904-
return path.join(tslintRuleDir, p + ".ts");
905-
});
906-
const tslintRulesOutFiles = tslintRules.map(function(p, i) {
907-
const pathname = path.join(builtLocalDirectory, "tslint", p + ".js");
908-
gulp.task(pathname, false, [], () => {
909-
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ false);
910-
return gulp.src(tslintRulesFiles[i])
911-
.pipe(newer(pathname))
912-
.pipe(sourcemaps.init())
913-
.pipe(tsc(settings))
914-
.pipe(sourcemaps.write("."))
915-
.pipe(gulp.dest(path.join(builtLocalDirectory, "tslint")));
916-
});
917-
return pathname;
917+
gulp.task("build-rules", "Compiles tslint rules to js", () => {
918+
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ false);
919+
const dest = path.join(builtLocalDirectory, "tslint");
920+
return gulp.src("scripts/tslint/**/*.ts")
921+
.pipe(newer({
922+
dest,
923+
ext: ".js"
924+
}))
925+
.pipe(sourcemaps.init())
926+
.pipe(tsc(settings))
927+
.pipe(sourcemaps.write("."))
928+
.pipe(gulp.dest(dest));
918929
});
919930

920-
gulp.task("build-rules", "Compiles tslint rules to js", tslintRulesOutFiles);
921-
922-
923-
function getLinterOptions() {
924-
return {
925-
configuration: require("./tslint.json"),
926-
formatter: "prose",
927-
formattersDirectory: undefined,
928-
rulesDirectory: "built/local/tslint"
929-
};
930-
}
931-
932-
function lintFileContents(options, path, contents) {
933-
const ll = new Linter(path, contents, options);
934-
console.log("Linting '" + path + "'.");
935-
return ll.lint();
936-
}
937-
938-
function lintFile(options, path) {
939-
const contents = fs.readFileSync(path, "utf8");
940-
return lintFileContents(options, path, contents);
941-
}
942-
943931
const lintTargets = [
944932
"Gulpfile.ts",
945933
"src/compiler/**/*.ts",
@@ -948,29 +936,75 @@ const lintTargets = [
948936
"src/server/**/*.ts",
949937
"scripts/tslint/**/*.ts",
950938
"src/services/**/*.ts",
939+
"tests/*.ts", "tests/webhost/*.ts" // Note: does *not* descend recursively
951940
];
952941

942+
function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback: (failures: number) => void, failures: number) {
943+
const file = files.pop();
944+
if (file) {
945+
console.log(`Linting '${file.path}'.`);
946+
child.send({ kind: "file", name: file.path });
947+
}
948+
else {
949+
child.send({ kind: "close" });
950+
callback(failures);
951+
}
952+
}
953+
954+
function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) {
955+
const child = cp.fork("./scripts/parallel-lint");
956+
let failures = 0;
957+
child.on("message", function(data) {
958+
switch (data.kind) {
959+
case "result":
960+
if (data.failures > 0) {
961+
failures += data.failures;
962+
console.log(data.output);
963+
}
964+
sendNextFile(files, child, callback, failures);
965+
break;
966+
case "error":
967+
console.error(data.error);
968+
failures++;
969+
sendNextFile(files, child, callback, failures);
970+
break;
971+
}
972+
});
973+
sendNextFile(files, child, callback, failures);
974+
}
953975

954976
gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => {
955977
const fileMatcher = RegExp(cmdLineOptions["files"]);
956-
const lintOptions = getLinterOptions();
957-
let failed = 0;
958-
return gulp.src(lintTargets)
959-
.pipe(insert.transform((contents, file) => {
960-
if (!fileMatcher.test(file.path)) return contents;
961-
const result = lintFile(lintOptions, file.path);
962-
if (result.failureCount > 0) {
963-
console.log(result.output);
964-
failed += result.failureCount;
978+
if (fold.isTravis()) console.log(fold.start("lint"));
979+
980+
let files: {stat: fs.Stats, path: string}[] = [];
981+
return gulp.src(lintTargets, { read: false })
982+
.pipe(through2.obj((chunk, enc, cb) => {
983+
files.push(chunk);
984+
cb();
985+
}, (cb) => {
986+
files = files.filter(file => fileMatcher.test(file.path)).sort((filea, fileb) => filea.stat.size - fileb.stat.size);
987+
const workerCount = (process.env.workerCount && +process.env.workerCount) || os.cpus().length;
988+
for (let i = 0; i < workerCount; i++) {
989+
spawnLintWorker(files, finished);
965990
}
966-
return contents; // TODO (weswig): Automatically apply fixes? :3
967-
}))
968-
.on("end", () => {
969-
if (failed > 0) {
970-
console.error("Linter errors.");
971-
process.exit(1);
991+
992+
let completed = 0;
993+
let failures = 0;
994+
function finished(fails) {
995+
completed++;
996+
failures += fails;
997+
if (completed === workerCount) {
998+
if (fold.isTravis()) console.log(fold.end("lint"));
999+
if (failures > 0) {
1000+
throw new Error(`Linter errors: ${failures}`);
1001+
}
1002+
else {
1003+
cb();
1004+
}
1005+
}
9721006
}
973-
});
1007+
}));
9741008
});
9751009

9761010

0 commit comments

Comments
 (0)