Skip to content

Commit a81178e

Browse files
authored
Merge pull request #494 from lddubeau/experiment/support-extends
Initial work on getting support for "extends".
2 parents d0cd523 + f43e9f5 commit a81178e

File tree

22 files changed

+248
-92
lines changed

22 files changed

+248
-92
lines changed

lib/main.ts

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ function getTypeScript(typescript: typeof ts) {
4646
}
4747
}
4848

49-
function getCompilerOptions(settings: compile.Settings, projectPath: string, configFileName: string): ts.CompilerOptions {
50-
let typescript = getTypeScript(settings.typescript);
51-
49+
function checkAndNormalizeSettings(settings: compile.Settings): void {
5250
if (settings.sourceRoot !== undefined) {
5351
console.warn('gulp-typescript: sourceRoot isn\'t supported any more. Use sourceRoot option of gulp-sourcemaps instead.')
5452
}
@@ -64,33 +62,30 @@ function getCompilerOptions(settings: compile.Settings, projectPath: string, con
6462
"The non-standard option sortOutput has been removed as of gulp-typescript 3.0.\nYour project will probably compile without this option.\nOtherwise, if you're using gulp-concat, you should remove gulp-concat and use the outFile option instead.");
6563
}
6664

67-
// Copy settings and remove several options
68-
const newSettings: compile.Settings = {};
69-
for (const option of Object.keys(settings)) {
70-
if (option === 'declarationFiles') {
71-
newSettings.declaration = settings.declarationFiles;
72-
continue;
73-
}
74-
if (option === 'noExternalResolve' ||
75-
option === 'sortOutput' ||
76-
option === 'typescript' ||
77-
option === 'sourceMap' ||
78-
option === 'inlineSourceMap' ||
79-
option === 'sourceRoot' ||
80-
option === 'inlineSources') continue;
81-
82-
newSettings[option] = settings[option];
65+
if (settings.declarationFiles) {
66+
settings.declaration = settings.declarationFiles;
67+
delete settings.declarationFiles;
8368
}
8469

85-
const result = typescript.convertCompilerOptionsFromJson(newSettings, projectPath, configFileName);
70+
delete settings.noExternalResolve;
71+
delete settings.sortOutput;
72+
delete settings.typescript;
73+
delete (settings as any).sourceMap;
74+
delete (settings as any).inlineSourceMap;
75+
delete settings.sourceRoot;
76+
delete (settings as any).inlineSources;
77+
}
78+
79+
function normalizeCompilerOptions(options: ts.CompilerOptions): void {
80+
options.sourceMap = true;
81+
(options as any).suppressOutputPathCheck = true;
82+
}
83+
84+
function reportErrors(errors: ts.Diagnostic[], typescript: typeof ts): void {
8685
const reporter = _reporter.defaultReporter();
87-
for (const error of result.errors) {
86+
for (const error of errors) {
8887
reporter.error(utils.getError(error, typescript), typescript);
8988
}
90-
result.options.sourceMap = true;
91-
(result.options as any).suppressOutputPathCheck = true;
92-
93-
return result.options;
9489
}
9590

9691
module compile {
@@ -149,36 +144,59 @@ module compile {
149144
let tsConfigFileName: string = undefined;
150145
let tsConfigContent: TsConfig = undefined;
151146
let projectDirectory = process.cwd();
147+
let typescript;
148+
let compilerOptions: ts.CompilerOptions;
149+
let fileName: string;
150+
settings = { ...settings }; // Shallow copy the settings.
152151
if (fileNameOrSettings !== undefined) {
153152
if (typeof fileNameOrSettings === 'string') {
153+
fileName = fileNameOrSettings;
154+
} else {
155+
settings = fileNameOrSettings || {};
156+
}
157+
158+
typescript = getTypeScript(settings.typescript);
159+
checkAndNormalizeSettings(settings);
160+
161+
const settingsResult = typescript.convertCompilerOptionsFromJson(settings, projectDirectory);
162+
163+
if (settingsResult.errors) {
164+
reportErrors(settingsResult.errors, typescript);
165+
}
166+
167+
compilerOptions = settingsResult.options;
168+
169+
if (fileName) {
154170
tsConfigFileName = path.resolve(process.cwd(), fileNameOrSettings);
155171
projectDirectory = path.dirname(tsConfigFileName);
156-
// Load file and strip BOM, since JSON.parse fails to parse if there's a BOM present
157-
let tsConfigText = fs.readFileSync(tsConfigFileName).toString();
158-
const typescript = getTypeScript(settings && settings.typescript);
159-
const tsConfig = typescript.parseConfigFileTextToJson(tsConfigFileName, tsConfigText);
160-
tsConfigContent = tsConfig.config || {};
172+
let tsConfig = typescript.readConfigFile(tsConfigFileName, typescript.sys.readFile);
161173
if (tsConfig.error) {
162174
console.log(tsConfig.error.messageText);
163175
}
164-
let newSettings: any = {};
165-
if (tsConfigContent.compilerOptions) {
166-
for (const key of Object.keys(tsConfigContent.compilerOptions)) {
167-
newSettings[key] = tsConfigContent.compilerOptions[key];
168-
}
169-
}
170-
if (settings) {
171-
for (const key of Object.keys(settings)) {
172-
newSettings[key] = settings[key];
173-
}
176+
177+
let parsed: ts.ParsedCommandLine = tsConfig.config &&
178+
typescript.parseJsonConfigFileContent(
179+
tsConfig.config,
180+
typescript.sys,
181+
path.resolve(projectDirectory),
182+
settings,
183+
path.basename(tsConfigFileName));
184+
185+
tsConfigContent = {
186+
compilerOptions: parsed.options,
187+
files: parsed.fileNames,
188+
};
189+
190+
if (parsed.errors) {
191+
reportErrors(parsed.errors, typescript);
174192
}
175-
settings = newSettings;
176-
} else {
177-
settings = fileNameOrSettings;
193+
194+
compilerOptions = parsed.options;
178195
}
179196
}
180197

181-
const project = _project.setupProject(projectDirectory, tsConfigContent, getCompilerOptions(settings, projectDirectory, tsConfigFileName), getTypeScript(settings.typescript));
198+
normalizeCompilerOptions(compilerOptions);
199+
const project = _project.setupProject(projectDirectory, tsConfigContent, compilerOptions, typescript);
182200

183201
return project;
184202
}

release/main.js

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
"use strict";
2-
var fs = require("fs");
2+
var __assign = (this && this.__assign) || Object.assign || function(t) {
3+
for (var s, i = 1, n = arguments.length; i < n; i++) {
4+
s = arguments[i];
5+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6+
t[p] = s[p];
7+
}
8+
return t;
9+
};
310
var path = require("path");
411
var _project = require("./project");
512
var utils = require("./utils");
@@ -34,8 +41,7 @@ function getTypeScript(typescript) {
3441
throw new Error("TypeScript not installed");
3542
}
3643
}
37-
function getCompilerOptions(settings, projectPath, configFileName) {
38-
var typescript = getTypeScript(settings.typescript);
44+
function checkAndNormalizeSettings(settings) {
3945
if (settings.sourceRoot !== undefined) {
4046
console.warn('gulp-typescript: sourceRoot isn\'t supported any more. Use sourceRoot option of gulp-sourcemaps instead.');
4147
}
@@ -45,72 +51,74 @@ function getCompilerOptions(settings, projectPath, configFileName) {
4551
if (settings.sortOutput !== undefined) {
4652
utils.deprecate("sortOutput is deprecated", "your project might work without it", "The non-standard option sortOutput has been removed as of gulp-typescript 3.0.\nYour project will probably compile without this option.\nOtherwise, if you're using gulp-concat, you should remove gulp-concat and use the outFile option instead.");
4753
}
48-
// Copy settings and remove several options
49-
var newSettings = {};
50-
for (var _i = 0, _a = Object.keys(settings); _i < _a.length; _i++) {
51-
var option = _a[_i];
52-
if (option === 'declarationFiles') {
53-
newSettings.declaration = settings.declarationFiles;
54-
continue;
55-
}
56-
if (option === 'noExternalResolve' ||
57-
option === 'sortOutput' ||
58-
option === 'typescript' ||
59-
option === 'sourceMap' ||
60-
option === 'inlineSourceMap' ||
61-
option === 'sourceRoot' ||
62-
option === 'inlineSources')
63-
continue;
64-
newSettings[option] = settings[option];
54+
if (settings.declarationFiles) {
55+
settings.declaration = settings.declarationFiles;
56+
delete settings.declarationFiles;
6557
}
66-
var result = typescript.convertCompilerOptionsFromJson(newSettings, projectPath, configFileName);
58+
delete settings.noExternalResolve;
59+
delete settings.sortOutput;
60+
delete settings.typescript;
61+
delete settings.sourceMap;
62+
delete settings.inlineSourceMap;
63+
delete settings.sourceRoot;
64+
delete settings.inlineSources;
65+
}
66+
function normalizeCompilerOptions(options) {
67+
options.sourceMap = true;
68+
options.suppressOutputPathCheck = true;
69+
}
70+
function reportErrors(errors, typescript) {
6771
var reporter = _reporter.defaultReporter();
68-
for (var _b = 0, _c = result.errors; _b < _c.length; _b++) {
69-
var error = _c[_b];
72+
for (var _i = 0, errors_1 = errors; _i < errors_1.length; _i++) {
73+
var error = errors_1[_i];
7074
reporter.error(utils.getError(error, typescript), typescript);
7175
}
72-
result.options.sourceMap = true;
73-
result.options.suppressOutputPathCheck = true;
74-
return result.options;
7576
}
7677
(function (compile) {
7778
compile.reporter = _reporter;
7879
function createProject(fileNameOrSettings, settings) {
7980
var tsConfigFileName = undefined;
8081
var tsConfigContent = undefined;
8182
var projectDirectory = process.cwd();
83+
var typescript;
84+
var compilerOptions;
85+
var fileName;
86+
settings = __assign({}, settings); // Shallow copy the settings.
8287
if (fileNameOrSettings !== undefined) {
8388
if (typeof fileNameOrSettings === 'string') {
89+
fileName = fileNameOrSettings;
90+
}
91+
else {
92+
settings = fileNameOrSettings || {};
93+
}
94+
typescript = getTypeScript(settings.typescript);
95+
checkAndNormalizeSettings(settings);
96+
var settingsResult = typescript.convertCompilerOptionsFromJson(settings, projectDirectory);
97+
if (settingsResult.errors) {
98+
reportErrors(settingsResult.errors, typescript);
99+
}
100+
compilerOptions = settingsResult.options;
101+
if (fileName) {
84102
tsConfigFileName = path.resolve(process.cwd(), fileNameOrSettings);
85103
projectDirectory = path.dirname(tsConfigFileName);
86-
// Load file and strip BOM, since JSON.parse fails to parse if there's a BOM present
87-
var tsConfigText = fs.readFileSync(tsConfigFileName).toString();
88-
var typescript = getTypeScript(settings && settings.typescript);
89-
var tsConfig = typescript.parseConfigFileTextToJson(tsConfigFileName, tsConfigText);
90-
tsConfigContent = tsConfig.config || {};
104+
var tsConfig = typescript.readConfigFile(tsConfigFileName, typescript.sys.readFile);
91105
if (tsConfig.error) {
92106
console.log(tsConfig.error.messageText);
93107
}
94-
var newSettings = {};
95-
if (tsConfigContent.compilerOptions) {
96-
for (var _i = 0, _a = Object.keys(tsConfigContent.compilerOptions); _i < _a.length; _i++) {
97-
var key = _a[_i];
98-
newSettings[key] = tsConfigContent.compilerOptions[key];
99-
}
100-
}
101-
if (settings) {
102-
for (var _b = 0, _c = Object.keys(settings); _b < _c.length; _b++) {
103-
var key = _c[_b];
104-
newSettings[key] = settings[key];
105-
}
108+
var parsed = tsConfig.config &&
109+
typescript.parseJsonConfigFileContent(tsConfig.config, typescript.sys, path.resolve(projectDirectory), settings, path.basename(tsConfigFileName));
110+
tsConfigContent = {
111+
compilerOptions: parsed.options,
112+
files: parsed.fileNames,
113+
};
114+
if (parsed.errors) {
115+
reportErrors(parsed.errors, typescript);
106116
}
107-
settings = newSettings;
108-
}
109-
else {
110-
settings = fileNameOrSettings;
117+
compilerOptions = parsed.options;
111118
}
112119
}
113-
var project = _project.setupProject(projectDirectory, tsConfigContent, getCompilerOptions(settings, projectDirectory, tsConfigFileName), getTypeScript(settings.typescript));
120+
normalizeCompilerOptions(compilerOptions);
121+
var project = _project.setupProject(projectDirectory, tsConfigContent, compilerOptions, typescript);
114122
return project;
115123
}
116124
compile.createProject = createProject;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export declare class Hello {
2+
value: string;
3+
}

test/baselines/tsconfigExtends/2.0/dts/test-3.d.ts

Whitespace-only changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
{
3+
"transpileErrors": 0,
4+
"optionsErrors": 0,
5+
"syntaxErrors": 0,
6+
"globalErrors": 0,
7+
"semanticErrors": 0,
8+
"declarationErrors": 0,
9+
"emitErrors": 0,
10+
"emitSkipped": false
11+
}

test/baselines/tsconfigExtends/2.0/js/other-3.js

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/baselines/tsconfigExtends/2.0/js/other-3.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/baselines/tsconfigExtends/2.0/js/test-3.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/baselines/tsconfigExtends/2.0/js/test-3.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export declare class Hello {
2+
value: string;
3+
}

0 commit comments

Comments
 (0)