Skip to content

Commit 4e3cba1

Browse files
committed
Merge remote-tracking branch 'origin/master' into pathMappingModuleResolution
2 parents 0377e7a + 38215c6 commit 4e3cba1

117 files changed

Lines changed: 1260 additions & 548 deletions

File tree

Some content is hidden

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

Jakefile.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ var serverCoreSources = [
106106
return path.join(serverDirectory, f);
107107
});
108108

109+
var scriptSources = [
110+
"tslint/booleanTriviaRule.ts",
111+
"tslint/nextLineRule.ts",
112+
"tslint/noNullRule.ts",
113+
"tslint/preferConstRule.ts",
114+
"tslint/typeOperatorSpacingRule.ts"
115+
].map(function (f) {
116+
return path.join(scriptsDirectory, f);
117+
});
118+
109119
var serverSources = serverCoreSources.concat(servicesSources);
110120

111121
var languageServiceLibrarySources = [
@@ -365,7 +375,6 @@ file(builtGeneratedDiagnosticMessagesJSON,[generatedDiagnosticMessagesJSON], fun
365375
desc("Generates a diagnostic file in TypeScript based on an input JSON file");
366376
task("generate-diagnostics", [diagnosticInfoMapTs]);
367377

368-
369378
// Publish nightly
370379
var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
371380
var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
@@ -909,7 +918,8 @@ function lintFileAsync(options, path, cb) {
909918

910919
var lintTargets = compilerSources
911920
.concat(harnessCoreSources)
912-
.concat(serverCoreSources);
921+
.concat(serverCoreSources)
922+
.concat(scriptSources);
913923

914924
desc("Runs tslint on the compiler sources");
915925
task("lint", ["build-rules"], function() {

scripts/tslint/typeOperatorSpacingRule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ export class Rule extends Lint.Rules.AbstractRule {
1313
class TypeOperatorSpacingWalker extends Lint.RuleWalker {
1414
public visitNode(node: ts.Node) {
1515
if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) {
16-
let types = (<ts.UnionOrIntersectionTypeNode>node).types;
16+
const types = (<ts.UnionOrIntersectionTypeNode>node).types;
1717
let expectedStart = types[0].end + 2; // space, | or &
1818
for (let i = 1; i < types.length; i++) {
19-
let currentType = types[i];
19+
const currentType = types[i];
2020
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
2121
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
2222
this.addFailure(failure);

src/compiler/checker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ namespace ts {
4646
const compilerOptions = host.getCompilerOptions();
4747
const languageVersion = compilerOptions.target || ScriptTarget.ES3;
4848
const modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
49+
const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System;
4950

5051
const emitResolver = createResolver();
5152

@@ -768,9 +769,12 @@ namespace ts {
768769
const moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
769770
if (moduleSymbol) {
770771
const exportDefaultSymbol = resolveSymbol(moduleSymbol.exports["default"]);
771-
if (!exportDefaultSymbol) {
772+
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
772773
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
773774
}
775+
else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
776+
return resolveSymbol(moduleSymbol.exports["export="]) || resolveSymbol(moduleSymbol);
777+
}
774778
return exportDefaultSymbol;
775779
}
776780
}

src/compiler/commandLineParser.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,12 @@ namespace ts {
311311
{
312312
name: "allowJs",
313313
type: "boolean",
314-
description: Diagnostics.Allow_javascript_files_to_be_compiled,
314+
description: Diagnostics.Allow_javascript_files_to_be_compiled
315+
},
316+
{
317+
name: "allowSyntheticDefaultImports",
318+
type: "boolean",
319+
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
315320
}
316321
];
317322

src/compiler/declarationEmitter.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ namespace ts {
658658
}
659659
else {
660660
write("require(");
661-
writeTextOfNode(currentText, getExternalModuleImportEqualsDeclarationExpression(node));
661+
emitExternalModuleSpecifier(node);
662662
write(");");
663663
}
664664
writer.writeLine();
@@ -715,14 +715,23 @@ namespace ts {
715715
}
716716
write(" from ");
717717
}
718-
emitExternalModuleSpecifier(node.moduleSpecifier);
718+
emitExternalModuleSpecifier(node);
719719
write(";");
720720
writer.writeLine();
721721
}
722722

723-
function emitExternalModuleSpecifier(moduleSpecifier: Expression) {
724-
if (moduleSpecifier.kind === SyntaxKind.StringLiteral && isBundledEmit) {
725-
const moduleName = getExternalModuleNameFromDeclaration(host, resolver, moduleSpecifier.parent as (ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration));
723+
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration) {
724+
let moduleSpecifier: Node;
725+
if (parent.kind === SyntaxKind.ImportEqualsDeclaration) {
726+
const node = parent as ImportEqualsDeclaration;
727+
moduleSpecifier = getExternalModuleImportEqualsDeclarationExpression(node);
728+
}
729+
else {
730+
const node = parent as (ImportDeclaration | ExportDeclaration);
731+
moduleSpecifier = node.moduleSpecifier;
732+
}
733+
if (moduleSpecifier.kind === SyntaxKind.StringLiteral && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) {
734+
const moduleName = getExternalModuleNameFromDeclaration(host, resolver, parent);
726735
if (moduleName) {
727736
write("\"");
728737
write(moduleName);
@@ -765,7 +774,7 @@ namespace ts {
765774
}
766775
if (node.moduleSpecifier) {
767776
write(" from ");
768-
emitExternalModuleSpecifier(node.moduleSpecifier);
777+
emitExternalModuleSpecifier(node);
769778
}
770779
write(";");
771780
writer.writeLine();

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,6 +2136,10 @@
21362136
"category": "Message",
21372137
"code": 6010
21382138
},
2139+
"Allow default imports from modules with no default export. This does not affect code emit, just typechecking.": {
2140+
"category": "Message",
2141+
"code": 6011
2142+
},
21392143
"Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015' (experimental)": {
21402144
"category": "Message",
21412145
"code": 6015

src/compiler/emitter.ts

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5571,9 +5571,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
55715571
emitDecoratorsOfClass(node);
55725572
}
55735573

5574+
if (!(node.flags & NodeFlags.Export)) {
5575+
return;
5576+
}
55745577
// If this is an exported class, but not on the top level (i.e. on an internal
55755578
// module), export it
5576-
if (!isES6ExportedDeclaration(node) && (node.flags & NodeFlags.Export)) {
5579+
if (node.flags & NodeFlags.Default) {
5580+
// if this is a top level default export of decorated class, write the export after the declaration.
5581+
writeLine();
5582+
if (thisNodeIsDecorated && modulekind === ModuleKind.ES6) {
5583+
write("export default ");
5584+
emitDeclarationName(node);
5585+
write(";");
5586+
}
5587+
else if (modulekind === ModuleKind.System) {
5588+
write(`${exportFunctionForFile}("default", `);
5589+
emitDeclarationName(node);
5590+
write(");");
5591+
}
5592+
else if (modulekind !== ModuleKind.ES6) {
5593+
write(`exports.default = `);
5594+
emitDeclarationName(node);
5595+
write(";");
5596+
}
5597+
}
5598+
else if (node.parent.kind !== SyntaxKind.SourceFile || (modulekind !== ModuleKind.ES6 && !(node.flags & NodeFlags.Default))) {
55775599
writeLine();
55785600
emitStart(node);
55795601
emitModuleMemberName(node);
@@ -5582,13 +5604,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
55825604
emitEnd(node);
55835605
write(";");
55845606
}
5585-
else if (isES6ExportedDeclaration(node) && (node.flags & NodeFlags.Default) && thisNodeIsDecorated) {
5586-
// if this is a top level default export of decorated class, write the export after the declaration.
5587-
writeLine();
5588-
write("export default ");
5589-
emitDeclarationName(node);
5590-
write(";");
5591-
}
55925607
}
55935608

55945609
function emitClassLikeDeclarationBelowES6(node: ClassLikeDeclaration) {
@@ -6795,7 +6810,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
67956810
}
67966811
}
67976812

6798-
function getExternalModuleNameText(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string {
6813+
function getExternalModuleNameText(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, emitRelativePathAsModuleName: boolean): string {
6814+
if (emitRelativePathAsModuleName) {
6815+
const name = getExternalModuleNameFromDeclaration(host, resolver, importNode);
6816+
if (name) {
6817+
return `"${name}"`;
6818+
}
6819+
}
67996820
const moduleName = getExternalModuleName(importNode);
68006821
if (moduleName.kind === SyntaxKind.StringLiteral) {
68016822
return tryRenameExternalModule(<LiteralExpression>moduleName) || getLiteralText(<LiteralExpression>moduleName);
@@ -7355,7 +7376,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
73557376
const dependencyGroups: DependencyGroup[] = [];
73567377

73577378
for (let i = 0; i < externalImports.length; ++i) {
7358-
let text = getExternalModuleNameText(externalImports[i]);
7379+
const text = getExternalModuleNameText(externalImports[i], emitRelativePathAsModuleName);
73597380
if (hasProperty(groupIndices, text)) {
73607381
// deduplicate/group entries in dependency list by the dependency name
73617382
const groupIndex = groupIndices[text];
@@ -7371,12 +7392,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
73717392
write(", ");
73727393
}
73737394

7374-
if (emitRelativePathAsModuleName) {
7375-
const name = getExternalModuleNameFromDeclaration(host, resolver, externalImports[i]);
7376-
if (name) {
7377-
text = `"${name}"`;
7378-
}
7379-
}
73807395
write(text);
73817396
}
73827397
write(`], function(${exportFunctionForFile}) {`);
@@ -7419,14 +7434,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
74197434

74207435
for (const importNode of externalImports) {
74217436
// Find the name of the external module
7422-
let externalModuleName = getExternalModuleNameText(importNode);
7423-
7424-
if (emitRelativePathAsModuleName) {
7425-
const name = getExternalModuleNameFromDeclaration(host, resolver, importNode);
7426-
if (name) {
7427-
externalModuleName = `"${name}"`;
7428-
}
7429-
}
7437+
const externalModuleName = getExternalModuleNameText(importNode, emitRelativePathAsModuleName);
74307438

74317439
// Find the name of the module alias, if there is one
74327440
const importAliasName = getLocalNameForExternalImport(importNode);

src/compiler/program.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ namespace ts {
764764
getTypeChecker,
765765
getClassifiableNames,
766766
getDiagnosticsProducingTypeChecker,
767-
getCommonSourceDirectory: () => commonSourceDirectory,
767+
getCommonSourceDirectory,
768768
emit,
769769
getCurrentDirectory: () => currentDirectory,
770770
getNodeCount: () => getDiagnosticsProducingTypeChecker().getNodeCount(),
@@ -780,6 +780,25 @@ namespace ts {
780780

781781
return program;
782782

783+
function getCommonSourceDirectory() {
784+
if (typeof commonSourceDirectory === "undefined") {
785+
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
786+
// If a rootDir is specified and is valid use it as the commonSourceDirectory
787+
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
788+
}
789+
else {
790+
commonSourceDirectory = computeCommonSourceDirectory(files);
791+
}
792+
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
793+
// Make sure directory path ends with directory separator so this string can directly
794+
// used to replace with "" to get the relative path of the source file and the relative path doesn't
795+
// start with / making it rooted path
796+
commonSourceDirectory += directorySeparator;
797+
}
798+
}
799+
return commonSourceDirectory;
800+
}
801+
783802
function getClassifiableNames() {
784803
if (!classifiableNames) {
785804
// Initialize a checker so that all our files are bound.
@@ -1644,24 +1663,12 @@ namespace ts {
16441663
options.sourceRoot || // there is --sourceRoot specified
16451664
options.mapRoot) { // there is --mapRoot specified
16461665

1647-
if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
1648-
// If a rootDir is specified and is valid use it as the commonSourceDirectory
1649-
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
1650-
}
1651-
else {
1652-
// Compute the commonSourceDirectory from the input files
1653-
commonSourceDirectory = computeCommonSourceDirectory(files);
1654-
// If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
1655-
if (options.outDir && commonSourceDirectory === "" && forEach(files, file => getRootLength(file.fileName) > 1)) {
1656-
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
1657-
}
1658-
}
1666+
// Precalculate and cache the common source directory
1667+
const dir = getCommonSourceDirectory();
16591668

1660-
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
1661-
// Make sure directory path ends with directory separator so this string can directly
1662-
// used to replace with "" to get the relative path of the source file and the relative path doesn't
1663-
// start with / making it rooted path
1664-
commonSourceDirectory += directorySeparator;
1669+
// If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
1670+
if (options.outDir && dir === "" && forEach(files, file => getRootLength(file.fileName) > 1)) {
1671+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
16651672
}
16661673
}
16671674

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,6 +2381,7 @@ namespace ts {
23812381
paths?: PathSubstitutions;
23822382
rootDirs?: RootPaths;
23832383
traceModuleResolution?: boolean;
2384+
allowSyntheticDefaultImports?: boolean;
23842385
allowJs?: boolean;
23852386
/* @internal */ stripInternal?: boolean;
23862387

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1906,7 +1906,7 @@ namespace ts {
19061906
* Resolves a local path to a path which is absolute to the base of the emit
19071907
*/
19081908
export function getExternalModuleNameFromPath(host: EmitHost, fileName: string): string {
1909-
const dir = host.getCurrentDirectory();
1909+
const dir = toPath(host.getCommonSourceDirectory(), host.getCurrentDirectory(), f => host.getCanonicalFileName(f));
19101910
const relativePath = getRelativePathToDirectoryOrUrl(dir, fileName, dir, f => host.getCanonicalFileName(f), /*isAbsolutePathAnUrl*/ false);
19111911
return removeFileExtension(relativePath);
19121912
}

0 commit comments

Comments
 (0)