Skip to content

Commit cff0f83

Browse files
committed
Report errors in corrrect process for gulp-typescript-oop
1 parent 133bb9f commit cff0f83

File tree

8 files changed

+586
-222
lines changed

8 files changed

+586
-222
lines changed

Gulpfile.js

+48-19
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const produceLKGJs = "scripts/produceLKG.js";
4646
const word2mdJs = "scripts/word2md.js";
4747
gulp.task("scripts", /*help*/ false, () => project.compile(scriptsProject), {
4848
aliases: [
49-
configurePrereleaseJs,
49+
configurePrereleaseJs,
5050
processDiagnosticMessagesJs,
5151
generateLocalizedDiagnosticMessagesJs,
5252
produceLKGJs,
@@ -134,10 +134,11 @@ gulp.task(generatedLCGFile, /*help*/ false, [generateLocalizedDiagnosticMessages
134134

135135
gulp.task("localize", /*help*/ false, [generatedLCGFile]);
136136

137+
const servicesProject = "src/services/tsconfig.json";
137138
const typescriptServicesProject = "built/local/typescriptServices.tsconfig.json";
138139
gulp.task(typescriptServicesProject, /*help*/ false, () => {
139140
// NOTE: flatten services so that we can properly strip @internal
140-
project.flatten("src/services/tsconfig.json", typescriptServicesProject, {
141+
project.flatten(servicesProject, typescriptServicesProject, {
141142
compilerOptions: {
142143
"removeComments": true,
143144
"stripInternal": true,
@@ -148,7 +149,7 @@ gulp.task(typescriptServicesProject, /*help*/ false, () => {
148149

149150
const typescriptServicesJs = "built/local/typescriptServices.js";
150151
const typescriptServicesDts = "built/local/typescriptServices.d.ts";
151-
gulp.task(typescriptServicesJs, /*help*/ false, ["lib", "generate-diagnostics", typescriptServicesProject], () =>
152+
gulp.task(typescriptServicesJs, /*help*/ false, ["lib", "generate-diagnostics", typescriptServicesProject], () =>
152153
project.compile(typescriptServicesProject, { dts: files => files.pipe(convertConstEnums()) }),
153154
{ aliases: [typescriptServicesDts] });
154155

@@ -225,7 +226,7 @@ gulp.task(tsserverlibraryProject, /*help*/ false, () => {
225226
const tsserverlibraryJs = "built/local/tsserverlibrary.js";
226227
const tsserverlibraryDts = "built/local/tsserverlibrary.d.ts";
227228
gulp.task(tsserverlibraryJs, /*help*/ false, [typescriptServicesJs, tsserverlibraryProject], () =>
228-
project.compile(tsserverlibraryProject, {
229+
project.compile(tsserverlibraryProject, {
229230
dts: files => files
230231
.pipe(convertConstEnums())
231232
.pipe(append("\nexport = ts;\nexport as namespace ts;")),
@@ -253,21 +254,21 @@ gulp.task(specMd, /*help*/ false, [word2mdJs], () =>
253254
exec("cscript", ["//nologo", word2mdJs, path.resolve(specMd), path.resolve("doc/TypeScript Language Specification.docx")]));
254255

255256
gulp.task(
256-
"generate-spec",
257-
"Generates a Markdown version of the Language Specification",
257+
"generate-spec",
258+
"Generates a Markdown version of the Language Specification",
258259
[specMd]);
259260

260261
gulp.task("produce-LKG", /*help*/ false, ["scripts", "local", cancellationTokenJs, typingsInstallerJs, watchGuardJs, tscReleaseJs], () => {
261262
const expectedFiles = [
262-
tscReleaseJs,
263-
typescriptServicesJs,
264-
tsserverJs,
265-
typescriptJs,
266-
typescriptDts,
267-
typescriptServicesDts,
268-
tsserverlibraryDts,
269-
tsserverlibraryDts,
270-
typingsInstallerJs,
263+
tscReleaseJs,
264+
typescriptServicesJs,
265+
tsserverJs,
266+
typescriptJs,
267+
typescriptDts,
268+
typescriptServicesDts,
269+
tsserverlibraryDts,
270+
tsserverlibraryDts,
271+
typingsInstallerJs,
271272
cancellationTokenJs
272273
].concat(libraryTargets);
273274
const missingFiles = expectedFiles
@@ -286,8 +287,8 @@ gulp.task("produce-LKG", /*help*/ false, ["scripts", "local", cancellationTokenJ
286287
});
287288

288289
gulp.task(
289-
"LKG",
290-
"Makes a new LKG out of the built js files",
290+
"LKG",
291+
"Makes a new LKG out of the built js files",
291292
() => runSequence("clean-built", "produce-LKG"));
292293

293294
// Task to build the tests infrastructure using the built compiler
@@ -464,12 +465,40 @@ gulp.task(
464465
"Runs 'local'",
465466
["local"]);
466467

468+
gulp.task(
469+
"watch-diagnostics",
470+
/*help*/ false,
471+
[processDiagnosticMessagesJs],
472+
() => gulp.watch([diagnosticMessagesJson], [diagnosticInformationMapTs, builtGeneratedDiagnosticMessagesJson]));
473+
474+
gulp.task(
475+
"watch-lib",
476+
/*help*/ false,
477+
() => gulp.watch(["src/lib/**/*"], ["lib"]));
478+
467479
gulp.task(
468480
"watch-tsc",
469-
"Watches for changes to the build inputs for built/local/tsc.js",
470-
[typescriptServicesJs],
481+
/*help*/ false,
482+
["watch-diagnostics", "watch-lib", typescriptServicesJs],
471483
() => project.watch(tscProject, { typescript: "built" }));
472484

485+
gulp.task(
486+
"watch-services",
487+
/*help*/ false,
488+
["watch-diagnostics", "watch-lib", typescriptServicesJs],
489+
() => project.watch(servicesProject, { typescript: "built" }));
490+
491+
gulp.task(
492+
"watch-server",
493+
/*help*/ false,
494+
["watch-diagnostics", "watch-lib", typescriptServicesJs],
495+
() => project.watch(tsserverProject, { typescript: "built" }));
496+
497+
gulp.task(
498+
"watch-local",
499+
/*help*/ false,
500+
["watch-lib", "watch-tsc", "watch-services", "watch-server"]);
501+
473502
gulp.task(
474503
"watch",
475504
"Watches for changes to the build inputs for built/local/run.js executes runtests-parallel.",

package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/build/gulp-typescript-oop.js

-91
This file was deleted.
+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// @ts-check
2+
const path = require("path");
3+
const child_process = require("child_process");
4+
const tsc = require("gulp-typescript");
5+
const Vinyl = require("vinyl");
6+
const { Duplex, Readable } = require("stream");
7+
const protocol = require("./protocol");
8+
9+
/**
10+
* @param {string | undefined} tsConfigFileName
11+
* @param {tsc.Settings} settings
12+
* @param {CreateProjectOptions} options
13+
*
14+
* @typedef CreateProjectOptions
15+
* @property {string} [typescript]
16+
* @property {boolean} [parse]
17+
*/
18+
function createProject(tsConfigFileName, settings, options) {
19+
settings = Object.assign({}, settings);
20+
options = Object.assign({}, options);
21+
if (settings.typescript) throw new Error();
22+
23+
const localSettings = Object.assign({}, settings);
24+
if (options.typescript) {
25+
options.typescript = path.resolve(options.typescript);
26+
localSettings.typescript = require(options.typescript);
27+
}
28+
29+
const project = tsConfigFileName === undefined ? tsc.createProject(localSettings) : tsc.createProject(tsConfigFileName, localSettings);
30+
const wrappedProject = /** @type {tsc.Project} */((reporter = tsc.reporter.defaultReporter()) => {
31+
const ts = project.typescript;
32+
const proc = child_process.fork(require.resolve("./worker.js"), [], {
33+
// Prevent errors when debugging gulpfile due to the same debug port being passed to forked children.
34+
execArgv: []
35+
});
36+
/** @type {Map<string, import("vinyl")>} */
37+
const inputs = new Map();
38+
/** @type {Map<string, *>} */
39+
const sourceFiles = new Map();
40+
/** @type {protocol.SourceFileHost & protocol.VinylHost} */
41+
const host = {
42+
getVinyl(path) { return inputs.get(path); },
43+
getSourceFile(fileName) { return sourceFiles.get(fileName); },
44+
createSourceFile(fileName, text, languageVersion) {
45+
if (text === undefined) throw new Error("File not cached.");
46+
/** @type {protocol.SourceFile} */
47+
let file;
48+
if (options.parse) {
49+
file = ts.createSourceFile(fileName, text, languageVersion, /*setParentNodes*/ true);
50+
}
51+
else {
52+
// NOTE: the built-in reporters in gulp-typescript don't actually need a full
53+
// source file, so save time by faking one unless requested.
54+
file = /**@type {protocol.SourceFile}*/({
55+
pos: 0,
56+
end: text.length,
57+
kind: ts.SyntaxKind.SourceFile,
58+
fileName,
59+
text,
60+
languageVersion,
61+
statements: /**@type {*} */([]),
62+
endOfFileToken: { pos: text.length, end: text.length, kind: ts.SyntaxKind.EndOfFileToken },
63+
amdDependencies: /**@type {*} */([]),
64+
referencedFiles: /**@type {*} */([]),
65+
typeReferenceDirectives: /**@type {*} */([]),
66+
libReferenceDirectives: /**@type {*} */([]),
67+
languageVariant: ts.LanguageVariant.Standard,
68+
isDeclarationFile: /\.d\.ts$/.test(fileName),
69+
hasNoDefaultLib: /[\\/]lib\.[^\\/]+\.d\.ts$/.test(fileName)
70+
});
71+
}
72+
sourceFiles.set(fileName, file);
73+
return file;
74+
}
75+
};
76+
/** @type {Duplex & { js?: Readable, dts?: Readable }} */
77+
const compileStream = new Duplex({
78+
objectMode: true,
79+
read() {},
80+
/** @param {*} file */
81+
write(file, _encoding, callback) {
82+
inputs.set(file.path, file);
83+
proc.send(protocol.message.write(file));
84+
callback();
85+
},
86+
final(callback) {
87+
proc.send(protocol.message.final());
88+
callback();
89+
}
90+
});
91+
const jsStream = compileStream.js = new Readable({
92+
objectMode: true,
93+
read() {}
94+
});
95+
const dtsStream = compileStream.dts = new Readable({
96+
objectMode: true,
97+
read() {}
98+
});
99+
proc.send(protocol.message.createProject(tsConfigFileName, settings, options));
100+
proc.on("message", (/**@type {protocol.WorkerMessage}*/ message) => {
101+
switch (message.method) {
102+
case "write": {
103+
const file = protocol.vinylFromJson(message.params);
104+
compileStream.push(file);
105+
if (file.path.endsWith(".d.ts")) {
106+
dtsStream.push(file);
107+
}
108+
else {
109+
jsStream.push(file);
110+
}
111+
break;
112+
}
113+
case "final": {
114+
compileStream.push(null);
115+
jsStream.push(null);
116+
dtsStream.push(null);
117+
proc.kill(); // TODO(rbuckton): pool workers? may not be feasible due to gulp-typescript holding onto memory
118+
break;
119+
}
120+
case "error": {
121+
const error = protocol.errorFromJson(message.params);
122+
compileStream.emit("error", error);
123+
proc.kill(); // TODO(rbuckton): pool workers? may not be feasible due to gulp-typescript holding onto memory
124+
break;
125+
}
126+
case "reporter.error": {
127+
if (reporter.error) {
128+
const error = protocol.typeScriptErrorFromJson(message.params, host);
129+
reporter.error(error, project.typescript);
130+
}
131+
break;
132+
}
133+
case "reporter.finish": {
134+
if (reporter.finish) {
135+
reporter.finish(message.params);
136+
}
137+
}
138+
}
139+
});
140+
return /** @type {*} */(compileStream);
141+
});
142+
return Object.assign(wrappedProject, project);
143+
}
144+
145+
exports.createProject = createProject;

0 commit comments

Comments
 (0)