Skip to content

Commit a7cc863

Browse files
committed
Merge branch 'master' into sourceMapAndBreakpointDecorators
2 parents ba2238f + d0de238 commit a7cc863

1,483 files changed

Lines changed: 19452 additions & 15751 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.

src/compiler/checker.ts

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,16 +1028,12 @@ namespace ts {
10281028

10291029
// Module names are escaped in our symbol table. However, string literal values aren't.
10301030
// Escape the name in the "require(...)" clause to ensure we find the right symbol.
1031-
let moduleName = escapeIdentifier(moduleReferenceLiteral.text);
1031+
const moduleName = escapeIdentifier(moduleReferenceLiteral.text);
10321032

10331033
if (moduleName === undefined) {
10341034
return;
10351035
}
10361036

1037-
if (moduleName.indexOf("!") >= 0) {
1038-
moduleName = moduleName.substr(0, moduleName.indexOf("!"));
1039-
}
1040-
10411037
const isRelative = isExternalModuleNameRelative(moduleName);
10421038
if (!isRelative) {
10431039
const symbol = getSymbol(globals, "\"" + moduleName + "\"", SymbolFlags.ValueModule);
@@ -5228,9 +5224,12 @@ namespace ts {
52285224
const id = relation !== identityRelation || apparentSource.id < target.id ? apparentSource.id + "," + target.id : target.id + "," + apparentSource.id;
52295225
const related = relation[id];
52305226
if (related !== undefined) {
5231-
// If we computed this relation already and it was failed and reported, or if we're not being asked to elaborate
5232-
// errors, we can use the cached value. Otherwise, recompute the relation
5233-
if (!elaborateErrors || (related === RelationComparisonResult.FailedAndReported)) {
5227+
if (elaborateErrors && related === RelationComparisonResult.Failed) {
5228+
// We are elaborating errors and the cached result is an unreported failure. Record the result as a reported
5229+
// failure and continue computing the relation such that errors get reported.
5230+
relation[id] = RelationComparisonResult.FailedAndReported;
5231+
}
5232+
else {
52345233
return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
52355234
}
52365235
}
@@ -6086,6 +6085,17 @@ namespace ts {
60866085
}
60876086

60886087
function inferFromTypes(source: Type, target: Type) {
6088+
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
6089+
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
6090+
// Source and target are both unions or both intersections. To improve the quality of
6091+
// inferences we first reduce the types by removing constituents that are identically
6092+
// matched by a constituent in the other type. For example, when inferring from
6093+
// 'string | string[]' to 'string | T', we reduce the types to 'string[]' and 'T'.
6094+
const reducedSource = reduceUnionOrIntersectionType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target);
6095+
const reducedTarget = reduceUnionOrIntersectionType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source);
6096+
source = reducedSource;
6097+
target = reducedTarget;
6098+
}
60896099
if (target.flags & TypeFlags.TypeParameter) {
60906100
// If target is a type parameter, make an inference, unless the source type contains
60916101
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
@@ -6096,7 +6106,6 @@ namespace ts {
60966106
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
60976107
return;
60986108
}
6099-
61006109
const typeParameters = context.typeParameters;
61016110
for (let i = 0; i < typeParameters.length; i++) {
61026111
if (target === typeParameters[i]) {
@@ -6244,6 +6253,41 @@ namespace ts {
62446253
}
62456254
}
62466255

6256+
function typeIdenticalToSomeType(source: Type, target: UnionOrIntersectionType): boolean {
6257+
for (const t of target.types) {
6258+
if (isTypeIdenticalTo(source, t)) {
6259+
return true;
6260+
}
6261+
}
6262+
return false;
6263+
}
6264+
6265+
/**
6266+
* Return the reduced form of the source type. This type is computed by by removing all source
6267+
* constituents that have an identical match in the target type.
6268+
*/
6269+
function reduceUnionOrIntersectionType(source: UnionOrIntersectionType, target: UnionOrIntersectionType) {
6270+
let sourceTypes = source.types;
6271+
let sourceIndex = 0;
6272+
let modified = false;
6273+
while (sourceIndex < sourceTypes.length) {
6274+
if (typeIdenticalToSomeType(sourceTypes[sourceIndex], target)) {
6275+
if (!modified) {
6276+
sourceTypes = sourceTypes.slice(0);
6277+
modified = true;
6278+
}
6279+
sourceTypes.splice(sourceIndex, 1);
6280+
}
6281+
else {
6282+
sourceIndex++;
6283+
}
6284+
}
6285+
if (modified) {
6286+
return source.flags & TypeFlags.Union ? getUnionType(sourceTypes, /*noSubtypeReduction*/ true) : getIntersectionType(sourceTypes);
6287+
}
6288+
return source;
6289+
}
6290+
62476291
function getInferenceCandidates(context: InferenceContext, index: number): Type[] {
62486292
const inferences = context.inferences[index];
62496293
return inferences.primary || inferences.secondary || emptyArray;

src/compiler/core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,4 +860,4 @@ namespace ts {
860860
}
861861
return copiedList;
862862
}
863-
}
863+
}

src/compiler/diagnosticMessages.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1622,7 +1622,7 @@
16221622
},
16231623
"Cannot assign an abstract constructor type to a non-abstract constructor type.": {
16241624
"category": "Error",
1625-
"code":2517
1625+
"code": 2517
16261626
},
16271627
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
16281628
"category": "Error",
@@ -2068,6 +2068,14 @@
20682068
"category": "Error",
20692069
"code": 5056
20702070
},
2071+
"Cannot find a tsconfig.json file at the specified directory: '{0}'": {
2072+
"category": "Error",
2073+
"code": 5057
2074+
},
2075+
"The specified path does not exist: '{0}'": {
2076+
"category": "Error",
2077+
"code": 5058
2078+
},
20712079

20722080
"Concatenate and emit output to single file.": {
20732081
"category": "Message",

src/compiler/emitter.ts

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
402402
*/
403403
argumentsName?: string;
404404

405+
/*
406+
* alias for 'this' from the calling code stack frame in case if this was used inside the converted loop
407+
*/
408+
thisName?: string;
409+
405410
/*
406411
* list of non-block scoped variable declarations that appear inside converted loop
407412
* such variable declarations should be moved outside the loop body
@@ -549,7 +554,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
549554
[ModuleKind.CommonJS]() {},
550555
};
551556

552-
557+
553558
return doEmit;
554559

555560
function doEmit(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
@@ -1992,6 +1997,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
19921997
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LexicalThis) {
19931998
write("_this");
19941999
}
2000+
else if (convertedLoopState) {
2001+
write(convertedLoopState.thisName || (convertedLoopState.thisName = makeUniqueName("this")));
2002+
}
19952003
else {
19962004
write("this");
19972005
}
@@ -3322,6 +3330,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
33223330
convertedLoopState.argumentsName = convertedOuterLoopState.argumentsName;
33233331
}
33243332

3333+
if (convertedOuterLoopState.thisName) {
3334+
// outer loop has already used 'this' so we've already have some name to alias it
3335+
// use the same name in all nested loops
3336+
convertedLoopState.thisName = convertedOuterLoopState.thisName;
3337+
}
3338+
33253339
if (convertedOuterLoopState.hoistedLocalVariables) {
33263340
// we've already collected some non-block scoped variable declarations in enclosing loop
33273341
// use the same storage in nested loop
@@ -3351,6 +3365,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
33513365
writeLine();
33523366
}
33533367
}
3368+
if (convertedLoopState.thisName) {
3369+
// if alias for this is set
3370+
if (convertedOuterLoopState) {
3371+
// pass it to outer converted loop
3372+
convertedOuterLoopState.thisName = convertedLoopState.thisName;
3373+
}
3374+
else {
3375+
// this is top level converted loop so we need to create an alias for 'this' here
3376+
// NOTE:
3377+
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
3378+
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
3379+
write(`var ${convertedLoopState.thisName} = this;`);
3380+
writeLine();
3381+
}
3382+
}
33543383

33553384
if (convertedLoopState.hoistedLocalVariables) {
33563385
// if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
@@ -5987,9 +6016,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
59876016
}
59886017

59896018
// Clone the type name and parent it to a location outside of the current declaration.
5990-
const typeName = cloneEntityName(node.typeName);
5991-
typeName.parent = location;
5992-
6019+
const typeName = cloneEntityName(node.typeName, location);
59936020
const result = resolver.getTypeReferenceSerializationKind(typeName);
59946021
switch (result) {
59956022
case TypeReferenceSerializationKind.Unknown:
@@ -7352,7 +7379,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
73527379
write(`], function(${exportFunctionForFile}) {`);
73537380
writeLine();
73547381
increaseIndent();
7355-
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
7382+
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true);
73567383
emitEmitHelpers(node);
73577384
emitCaptureThisForNodeIfNecessary(node);
73587385
emitSystemModuleBody(node, dependencyGroups, startIndex);
@@ -7462,7 +7489,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
74627489
writeModuleName(node, emitRelativePathAsModuleName);
74637490
emitAMDDependencies(node, /*includeNonAmdDependencies*/ true, emitRelativePathAsModuleName);
74647491
increaseIndent();
7465-
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
7492+
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true);
74667493
emitExportStarHelper();
74677494
emitCaptureThisForNodeIfNecessary(node);
74687495
emitLinesStartingAt(node.statements, startIndex);
@@ -7474,7 +7501,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
74747501
}
74757502

74767503
function emitCommonJSModule(node: SourceFile) {
7477-
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);
7504+
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false, /*ensureUseStrict*/ true);
74787505
emitEmitHelpers(node);
74797506
collectExternalModuleInfo(node);
74807507
emitExportStarHelper();
@@ -7503,7 +7530,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
75037530
})(`);
75047531
emitAMDFactoryHeader(dependencyNames);
75057532
increaseIndent();
7506-
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true);
7533+
const startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ true, /*ensureUseStrict*/ true);
75077534
emitExportStarHelper();
75087535
emitCaptureThisForNodeIfNecessary(node);
75097536
emitLinesStartingAt(node.statements, startIndex);
@@ -7645,19 +7672,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
76457672
}
76467673
}
76477674

7648-
function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean): number {
7675+
function isUseStrictPrologue(node: ExpressionStatement): boolean {
7676+
return !!(node.expression as StringLiteral).text.match(/use strict/);
7677+
}
7678+
7679+
function ensureUseStrictPrologue(startWithNewLine: boolean, writeUseStrict: boolean) {
7680+
if (writeUseStrict) {
7681+
if (startWithNewLine) {
7682+
writeLine();
7683+
}
7684+
write("\"use strict\";");
7685+
}
7686+
}
7687+
7688+
function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean, ensureUseStrict?: boolean): number {
7689+
let foundUseStrict = false;
76497690
for (let i = 0; i < statements.length; ++i) {
76507691
if (isPrologueDirective(statements[i])) {
7692+
if (isUseStrictPrologue(statements[i] as ExpressionStatement)) {
7693+
foundUseStrict = true;
7694+
}
76517695
if (startWithNewLine || i > 0) {
76527696
writeLine();
76537697
}
76547698
emit(statements[i]);
76557699
}
76567700
else {
7701+
ensureUseStrictPrologue(startWithNewLine || i > 0, !foundUseStrict && ensureUseStrict);
76577702
// return index of the first non prologue directive
76587703
return i;
76597704
}
76607705
}
7706+
ensureUseStrictPrologue(startWithNewLine, !foundUseStrict && ensureUseStrict);
76617707
return statements.length;
76627708
}
76637709

src/compiler/tsc.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,26 @@ namespace ts {
295295
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--project"), /* compilerHost */ undefined);
296296
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
297297
}
298-
configFileName = normalizePath(combinePaths(commandLine.options.project, "tsconfig.json"));
299298
if (commandLine.fileNames.length !== 0) {
300299
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line), /* compilerHost */ undefined);
301300
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
302301
}
302+
303+
const fileOrDirectory = normalizePath(commandLine.options.project);
304+
if (!fileOrDirectory /* current directory "." */ || sys.directoryExists(fileOrDirectory)) {
305+
configFileName = combinePaths(fileOrDirectory, "tsconfig.json");
306+
if (!sys.fileExists(configFileName)) {
307+
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
308+
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
309+
}
310+
}
311+
else {
312+
configFileName = fileOrDirectory;
313+
if (!sys.fileExists(configFileName)) {
314+
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, commandLine.options.project), /* compilerHost */ undefined);
315+
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
316+
}
317+
}
303318
}
304319
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
305320
const searchPath = normalizePath(sys.getCurrentDirectory());

0 commit comments

Comments
 (0)