Skip to content

Commit b5f4c07

Browse files
author
Kanchalai Tanglertsampan
committed
Merge branch 'master' into mergeMaster_09/01
2 parents d7a20f5 + 8038eb9 commit b5f4c07

File tree

153 files changed

+1289
-1403
lines changed

Some content is hidden

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

153 files changed

+1289
-1403
lines changed

src/compiler/checker.ts

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,8 +1024,8 @@ namespace ts {
10241024
}
10251025
}
10261026

1027-
function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration {
1028-
return findMap(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined);
1027+
function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration | undefined {
1028+
return forEach(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined);
10291029
}
10301030

10311031
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
@@ -1192,6 +1192,7 @@ namespace ts {
11921192
if (!links.target) {
11931193
links.target = resolvingSymbol;
11941194
const node = getDeclarationOfAliasSymbol(symbol);
1195+
Debug.assert(!!node);
11951196
const target = getTargetOfAliasDeclaration(node);
11961197
if (links.target === resolvingSymbol) {
11971198
links.target = target || unknownSymbol;
@@ -1227,6 +1228,7 @@ namespace ts {
12271228
if (!links.referenced) {
12281229
links.referenced = true;
12291230
const node = getDeclarationOfAliasSymbol(symbol);
1231+
Debug.assert(!!node);
12301232
if (node.kind === SyntaxKind.ExportAssignment) {
12311233
// export default <symbol>
12321234
checkExpressionCached((<ExportAssignment>node).expression);
@@ -3348,7 +3350,13 @@ namespace ts {
33483350
// Otherwise, fall back to 'any'.
33493351
else {
33503352
if (compilerOptions.noImplicitAny) {
3351-
error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation, symbolToString(symbol));
3353+
if (setter) {
3354+
error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
3355+
}
3356+
else {
3357+
Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
3358+
error(getter, Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
3359+
}
33523360
}
33533361
type = anyType;
33543362
}
@@ -5374,7 +5382,7 @@ namespace ts {
53745382
while (i > 0) {
53755383
i--;
53765384
if (isSubtypeOfAny(types[i], types)) {
5377-
types.splice(i, 1);
5385+
orderedRemoveItemAt(types, i);
53785386
}
53795387
}
53805388
}
@@ -8758,7 +8766,7 @@ namespace ts {
87588766
// The location isn't a reference to the given symbol, meaning we're being asked
87598767
// a hypothetical question of what type the symbol would have if there was a reference
87608768
// to it at the given location. Since we have no control flow information for the
8761-
// hypotherical reference (control flow information is created and attached by the
8769+
// hypothetical reference (control flow information is created and attached by the
87628770
// binder), we simply return the declared type of the symbol.
87638771
return getTypeOfSymbol(symbol);
87648772
}
@@ -11993,18 +12001,12 @@ namespace ts {
1199312001
// Function interface, since they have none by default. This is a bit of a leap of faith
1199412002
// that the user will not add any.
1199512003
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
11996-
1199712004
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
11998-
// TS 1.0 spec: 4.12
11999-
// If FuncExpr is of type Any, or of an object type that has no call or construct signatures
12000-
// but is a subtype of the Function interface, the call is an untyped function call. In an
12001-
// untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
12005+
12006+
// TS 1.0 Spec: 4.12
12007+
// In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
1200212008
// types are provided for the argument expressions, and the result is always of type Any.
12003-
// We exclude union types because we may have a union of function types that happen to have
12004-
// no common signatures.
12005-
if (isTypeAny(funcType) ||
12006-
(isTypeAny(apparentType) && funcType.flags & TypeFlags.TypeParameter) ||
12007-
(!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
12009+
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
1200812010
// The unknownType indicates that an error already occurred (and was reported). No
1200912011
// need to report another error in this case.
1201012012
if (funcType !== unknownType && node.typeArguments) {
@@ -12027,6 +12029,29 @@ namespace ts {
1202712029
return resolveCall(node, callSignatures, candidatesOutArray);
1202812030
}
1202912031

12032+
/**
12033+
* TS 1.0 spec: 4.12
12034+
* If FuncExpr is of type Any, or of an object type that has no call or construct signatures
12035+
* but is a subtype of the Function interface, the call is an untyped function call.
12036+
*/
12037+
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) {
12038+
if (isTypeAny(funcType)) {
12039+
return true;
12040+
}
12041+
if (isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter) {
12042+
return true;
12043+
}
12044+
if (!numCallSignatures && !numConstructSignatures) {
12045+
// We exclude union types because we may have a union of function types that happen to have
12046+
// no common signatures.
12047+
if (funcType.flags & TypeFlags.Union) {
12048+
return false;
12049+
}
12050+
return isTypeAssignableTo(funcType, globalFunctionType);
12051+
}
12052+
return false;
12053+
}
12054+
1203012055
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature {
1203112056
if (node.arguments && languageVersion < ScriptTarget.ES5) {
1203212057
const spreadIndex = getSpreadArgumentIndex(node.arguments);
@@ -12152,8 +12177,9 @@ namespace ts {
1215212177
}
1215312178

1215412179
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
12180+
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
1215512181

12156-
if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) {
12182+
if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) {
1215712183
return resolveUntypedCall(node);
1215812184
}
1215912185

@@ -12198,7 +12224,8 @@ namespace ts {
1219812224
}
1219912225

1220012226
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
12201-
if (funcType === anyType || (!callSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
12227+
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
12228+
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
1220212229
return resolveUntypedCall(node);
1220312230
}
1220412231

@@ -18885,7 +18912,13 @@ namespace ts {
1888518912
(augmentations || (augmentations = [])).push(file.moduleAugmentations);
1888618913
}
1888718914
if (file.symbol && file.symbol.globalExports) {
18888-
mergeSymbolTable(globals, file.symbol.globalExports);
18915+
// Merge in UMD exports with first-in-wins semantics (see #9771)
18916+
const source = file.symbol.globalExports;
18917+
for (const id in source) {
18918+
if (!(id in globals)) {
18919+
globals[id] = source[id];
18920+
}
18921+
}
1888918922
}
1889018923
if ((compilerOptions.isolatedModules || isExternalModule(file)) && !file.isDeclarationFile) {
1889118924
const fileRequestedExternalEmitHelpers = file.flags & NodeFlags.EmitHelperFlags;

src/compiler/commandLineParser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ namespace ts {
891891
function convertCompilerOptionsFromJsonWorker(jsonOptions: any,
892892
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
893893

894-
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true } : {};
894+
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true, maxNodeModuleJsDepth: 2 } : {};
895895
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
896896
return options;
897897
}

src/compiler/core.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,10 @@ namespace ts {
199199
return count;
200200
}
201201

202-
export function filter<T, U extends T>(array: T[], f: (x: T) => x is U): U[];
203-
export function filter<T>(array: T[], f: (x: T) => boolean): T[]
202+
/**
203+
* Filters an array by a predicate function. Returns the same array instance if the predicate is
204+
* true for all elements, otherwise returns a new array instance containing the filtered subset.
205+
*/
204206
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
205207
if (array) {
206208
const len = array.length;
@@ -1717,20 +1719,39 @@ namespace ts {
17171719
return "";
17181720
}
17191721

1720-
export function copyListRemovingItem<T>(item: T, list: T[]) {
1721-
const copiedList: T[] = [];
1722-
for (const e of list) {
1723-
if (e !== item) {
1724-
copiedList.push(e);
1722+
/** Remove an item from an array, moving everything to its right one space left. */
1723+
export function orderedRemoveItemAt<T>(array: T[], index: number): void {
1724+
// This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
1725+
for (let i = index; i < array.length - 1; i++) {
1726+
array[i] = array[i + 1];
1727+
}
1728+
array.pop();
1729+
}
1730+
1731+
export function unorderedRemoveItemAt<T>(array: T[], index: number): void {
1732+
// Fill in the "hole" left at `index`.
1733+
array[index] = array[array.length - 1];
1734+
array.pop();
1735+
}
1736+
1737+
/** Remove the *first* occurrence of `item` from the array. */
1738+
export function unorderedRemoveItem<T>(array: T[], item: T): void {
1739+
unorderedRemoveFirstItemWhere(array, element => element === item);
1740+
}
1741+
1742+
/** Remove the *first* element satisfying `predicate`. */
1743+
function unorderedRemoveFirstItemWhere<T>(array: T[], predicate: (element: T) => boolean): void {
1744+
for (let i = 0; i < array.length; i++) {
1745+
if (predicate(array[i])) {
1746+
unorderedRemoveItemAt(array, i);
1747+
break;
17251748
}
17261749
}
1727-
return copiedList;
17281750
}
17291751

1730-
export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
1731-
return useCaseSensitivefileNames
1752+
export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean): (fileName: string) => string {
1753+
return useCaseSensitiveFileNames
17321754
? ((fileName) => fileName)
17331755
: ((fileName) => fileName.toLowerCase());
17341756
}
1735-
17361757
}

src/compiler/declarationEmitter.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,8 +1133,10 @@ namespace ts {
11331133
// it if it's not a well known symbol. In that case, the text of the name will be exactly
11341134
// what we want, namely the name expression enclosed in brackets.
11351135
writeTextOfNode(currentText, node.name);
1136-
// If optional property emit ?
1137-
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.Parameter) && hasQuestionToken(node)) {
1136+
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
1137+
// we don't want to emit property declaration with "?"
1138+
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
1139+
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
11381140
write("?");
11391141
}
11401142
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {

src/compiler/diagnosticMessages.json

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2871,11 +2871,7 @@
28712871
"Element implicitly has an 'any' type because index expression is not of type 'number'.": {
28722872
"category": "Error",
28732873
"code": 7015
2874-
},
2875-
"Property '{0}' implicitly has type 'any', because its 'set' accessor lacks a type annotation.": {
2876-
"category": "Error",
2877-
"code": 7016
2878-
},
2874+
},
28792875
"Index signature of object type implicitly has an 'any' type.": {
28802876
"category": "Error",
28812877
"code": 7017
@@ -2932,6 +2928,14 @@
29322928
"category": "Error",
29332929
"code": 7031
29342930
},
2931+
"Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation.": {
2932+
"category": "Error",
2933+
"code": 7032
2934+
},
2935+
"Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation.": {
2936+
"category": "Error",
2937+
"code": 7033
2938+
},
29352939
"You cannot rename this element.": {
29362940
"category": "Error",
29372941
"code": 8000

src/compiler/parser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,7 @@ namespace ts {
23382338
token() === SyntaxKind.LessThanToken ||
23392339
token() === SyntaxKind.QuestionToken ||
23402340
token() === SyntaxKind.ColonToken ||
2341+
token() === SyntaxKind.CommaToken ||
23412342
canParseSemicolon();
23422343
}
23432344
return false;

src/compiler/program.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ namespace ts {
11021102
// - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
11031103
// As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
11041104
// The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
1105-
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2;
1105+
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
11061106
let currentNodeModulesDepth = 0;
11071107

11081108
// If a module has some of its imports skipped due to being at the depth limit under node_modules, then track

src/compiler/sys.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,10 @@ namespace ts {
291291
function removeFileWatcherCallback(filePath: string, callback: FileWatcherCallback) {
292292
const callbacks = fileWatcherCallbacks[filePath];
293293
if (callbacks) {
294-
const newCallbacks = copyListRemovingItem(callback, callbacks);
295-
if (newCallbacks.length === 0) {
294+
unorderedRemoveItem(callbacks, callback);
295+
if (callbacks.length === 0) {
296296
delete fileWatcherCallbacks[filePath];
297297
}
298-
else {
299-
fileWatcherCallbacks[filePath] = newCallbacks;
300-
}
301298
}
302299
}
303300

src/compiler/tsc.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,7 @@ namespace ts {
482482
sourceFile.fileWatcher.close();
483483
sourceFile.fileWatcher = undefined;
484484
if (removed) {
485-
const index = rootFileNames.indexOf(sourceFile.fileName);
486-
if (index >= 0) {
487-
rootFileNames.splice(index, 1);
488-
}
485+
unorderedRemoveItem(rootFileNames, sourceFile.fileName);
489486
}
490487
startTimerForRecompilation();
491488
}

src/compiler/utilities.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,18 @@ namespace ts {
11201120
return undefined;
11211121
}
11221122

1123+
export function isCallLikeExpression(node: Node): node is CallLikeExpression {
1124+
switch (node.kind) {
1125+
case SyntaxKind.CallExpression:
1126+
case SyntaxKind.NewExpression:
1127+
case SyntaxKind.TaggedTemplateExpression:
1128+
case SyntaxKind.Decorator:
1129+
return true;
1130+
default:
1131+
return false;
1132+
}
1133+
}
1134+
11231135
export function getInvokedExpression(node: CallLikeExpression): Expression {
11241136
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
11251137
return (<TaggedTemplateExpression>node).tag;
@@ -3022,10 +3034,13 @@ namespace ts {
30223034
return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment;
30233035
}
30243036

3025-
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean {
3026-
return node.kind === SyntaxKind.ExpressionWithTypeArguments &&
3037+
/** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
3038+
export function tryGetClassExtendingExpressionWithTypeArguments(node: Node): ClassLikeDeclaration | undefined {
3039+
if (node.kind === SyntaxKind.ExpressionWithTypeArguments &&
30273040
(<HeritageClause>node.parent).token === SyntaxKind.ExtendsKeyword &&
3028-
isClassLike(node.parent.parent);
3041+
isClassLike(node.parent.parent)) {
3042+
return node.parent.parent;
3043+
}
30293044
}
30303045

30313046
export function isDestructuringAssignment(node: Node): node is BinaryExpression {
@@ -3058,6 +3073,10 @@ namespace ts {
30583073
}
30593074
}
30603075

3076+
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean {
3077+
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
3078+
}
3079+
30613080
export function isEntityNameExpression(node: Expression): node is EntityNameExpression {
30623081
return node.kind === SyntaxKind.Identifier ||
30633082
node.kind === SyntaxKind.PropertyAccessExpression && isEntityNameExpression((<PropertyAccessExpression>node).expression);

0 commit comments

Comments
 (0)