Skip to content

Commit eb9ad2a

Browse files
committed
Merge branch 'master' into see-tag
2 parents 96ec48d + 3b502f4 commit eb9ad2a

File tree

114 files changed

+1566
-396
lines changed

Some content is hidden

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

114 files changed

+1566
-396
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ See below for examples.
176176

177177
### Tests for multiple files
178178

179-
When you need to multiple files in a single test, use the `filename` tag:
179+
When you need to mimic having multiple files in a single test to test features such as "import", use the `filename` tag:
180180

181181
```ts
182182
// @filename: file1.ts

package-lock.json

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

src/compiler/binder.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,6 +2974,10 @@ namespace ts {
29742974
if (!isInJSFile(node) && !isFunctionSymbol(parentSymbol)) {
29752975
return;
29762976
}
2977+
const rootExpr = getLeftmostAccessExpression(node.left);
2978+
if (isIdentifier(rootExpr) && lookupSymbolForName(container, rootExpr.escapedText)!?.flags & SymbolFlags.Alias) {
2979+
return;
2980+
}
29772981
// Fix up parent pointers since we're going to use these nodes before we bind into them
29782982
setParent(node.left, node);
29792983
setParent(node.right, node);

src/compiler/checker.ts

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,12 @@ namespace ts {
248248
ExportNamespace = 1 << 2,
249249
}
250250

251+
const enum MinArgumentCountFlags {
252+
None = 0,
253+
StrongArityForUntypedJS = 1 << 0,
254+
VoidIsNonOptional = 1 << 1,
255+
}
256+
251257
function SymbolLinks(this: SymbolLinks) {
252258
}
253259

@@ -2410,7 +2416,7 @@ namespace ts {
24102416

24112417
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration | VariableDeclaration, dontResolveAlias: boolean): Symbol | undefined {
24122418
if (isVariableDeclaration(node) && node.initializer && isPropertyAccessExpression(node.initializer)) {
2413-
const name = (getLeftmostPropertyAccessExpression(node.initializer.expression) as CallExpression).arguments[0] as StringLiteral;
2419+
const name = (getLeftmostAccessExpression(node.initializer.expression) as CallExpression).arguments[0] as StringLiteral;
24142420
return isIdentifier(node.initializer.name)
24152421
? resolveSymbol(getPropertyOfType(resolveExternalModuleTypeByLiteral(name), node.initializer.name.escapedText))
24162422
: undefined;
@@ -2672,7 +2678,7 @@ namespace ts {
26722678
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
26732679
if (suggestion !== undefined) {
26742680
const suggestionName = symbolToString(suggestion);
2675-
const diagnostic = error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
2681+
const diagnostic = error(name, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
26762682
if (suggestion.valueDeclaration) {
26772683
addRelatedInfo(diagnostic,
26782684
createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName)
@@ -3051,7 +3057,12 @@ namespace ts {
30513057
symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning));
30523058
if (!symbol) {
30533059
if (!ignoreErrors) {
3054-
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), declarationNameToString(right));
3060+
const namespaceName = getFullyQualifiedName(namespace);
3061+
const declarationName = declarationNameToString(right);
3062+
const suggestion = getSuggestedSymbolForNonexistentModule(right, namespace);
3063+
suggestion ?
3064+
error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestion)) :
3065+
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName);
30553066
}
30563067
return undefined;
30573068
}
@@ -9703,7 +9714,7 @@ namespace ts {
97039714

97049715
// fill in any as-yet-unresolved late-bound members.
97059716
const lateSymbols = createSymbolTable() as UnderscoreEscapedMap<TransientSymbol>;
9706-
for (const decl of symbol.declarations) {
9717+
for (const decl of symbol.declarations || emptyArray) {
97079718
const members = getMembersOfDeclaration(decl);
97089719
if (members) {
97099720
for (const member of members) {
@@ -9859,6 +9870,7 @@ namespace ts {
98599870
sig.resolvedReturnType = resolvedReturnType;
98609871
sig.resolvedTypePredicate = resolvedTypePredicate;
98619872
sig.minArgumentCount = minArgumentCount;
9873+
sig.resolvedMinArgumentCount = undefined;
98629874
sig.target = undefined;
98639875
sig.mapper = undefined;
98649876
sig.unionSignatures = undefined;
@@ -11318,7 +11330,10 @@ namespace ts {
1131811330
const signature = getSignatureFromDeclaration(node.parent);
1131911331
const parameterIndex = node.parent.parameters.indexOf(node);
1132011332
Debug.assert(parameterIndex >= 0);
11321-
return parameterIndex >= getMinArgumentCount(signature, /*strongArityForUntypedJS*/ true);
11333+
// Only consider syntactic or instantiated parameters as optional, not `void` parameters as this function is used
11334+
// in grammar checks and checking for `void` too early results in parameter types widening too early
11335+
// and causes some noImplicitAny errors to be lost.
11336+
return parameterIndex >= getMinArgumentCount(signature, MinArgumentCountFlags.StrongArityForUntypedJS | MinArgumentCountFlags.VoidIsNonOptional);
1132211337
}
1132311338
const iife = getImmediatelyInvokedFunctionExpression(node.parent);
1132411339
if (iife) {
@@ -23023,12 +23038,16 @@ namespace ts {
2302323038
const name = declaration.propertyName || declaration.name;
2302423039
const parentType = getContextualTypeForVariableLikeDeclaration(parent) ||
2302523040
parent.kind !== SyntaxKind.BindingElement && parent.initializer && checkDeclarationInitializer(parent);
23026-
if (parentType && !isBindingPattern(name) && !isComputedNonLiteralName(name)) {
23027-
const nameType = getLiteralTypeFromPropertyName(name);
23028-
if (isTypeUsableAsPropertyName(nameType)) {
23029-
const text = getPropertyNameFromType(nameType);
23030-
return getTypeOfPropertyOfType(parentType, text);
23031-
}
23041+
if (!parentType || isBindingPattern(name) || isComputedNonLiteralName(name)) return undefined;
23042+
if (parent.name.kind === SyntaxKind.ArrayBindingPattern) {
23043+
const index = indexOfNode(declaration.parent.elements, declaration);
23044+
if (index < 0) return undefined;
23045+
return getContextualTypeForElementExpression(parentType, index);
23046+
}
23047+
const nameType = getLiteralTypeFromPropertyName(name);
23048+
if (isTypeUsableAsPropertyName(nameType)) {
23049+
const text = getPropertyNameFromType(nameType);
23050+
return getTypeOfPropertyOfType(parentType, text);
2303223051
}
2303323052
}
2303423053

@@ -28024,21 +28043,40 @@ namespace ts {
2802428043
return length;
2802528044
}
2802628045

28027-
function getMinArgumentCount(signature: Signature, strongArityForUntypedJS?: boolean) {
28028-
if (signatureHasRestParameter(signature)) {
28029-
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
28030-
if (isTupleType(restType)) {
28031-
const firstOptionalIndex = findIndex(restType.target.elementFlags, f => !(f & ElementFlags.Required));
28032-
const requiredCount = firstOptionalIndex < 0 ? restType.target.fixedLength : firstOptionalIndex;
28033-
if (requiredCount > 0) {
28034-
return signature.parameters.length - 1 + requiredCount;
28046+
function getMinArgumentCount(signature: Signature, flags?: MinArgumentCountFlags) {
28047+
const strongArityForUntypedJS = flags! & MinArgumentCountFlags.StrongArityForUntypedJS;
28048+
const voidIsNonOptional = flags! & MinArgumentCountFlags.VoidIsNonOptional;
28049+
if (voidIsNonOptional || signature.resolvedMinArgumentCount === undefined) {
28050+
let minArgumentCount: number | undefined;
28051+
if (signatureHasRestParameter(signature)) {
28052+
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
28053+
if (isTupleType(restType)) {
28054+
const firstOptionalIndex = findIndex(restType.target.elementFlags, f => !(f & ElementFlags.Required));
28055+
const requiredCount = firstOptionalIndex < 0 ? restType.target.fixedLength : firstOptionalIndex;
28056+
if (requiredCount > 0) {
28057+
minArgumentCount = signature.parameters.length - 1 + requiredCount;
28058+
}
2803528059
}
2803628060
}
28061+
if (minArgumentCount === undefined) {
28062+
if (!strongArityForUntypedJS && signature.flags & SignatureFlags.IsUntypedSignatureInJSFile) {
28063+
return 0;
28064+
}
28065+
minArgumentCount = signature.minArgumentCount;
28066+
}
28067+
if (voidIsNonOptional) {
28068+
return minArgumentCount;
28069+
}
28070+
for (let i = minArgumentCount - 1; i >= 0; i--) {
28071+
const type = getTypeAtPosition(signature, i);
28072+
if (filterType(type, acceptsVoid).flags & TypeFlags.Never) {
28073+
break;
28074+
}
28075+
minArgumentCount = i;
28076+
}
28077+
signature.resolvedMinArgumentCount = minArgumentCount;
2803728078
}
28038-
if (!strongArityForUntypedJS && signature.flags & SignatureFlags.IsUntypedSignatureInJSFile) {
28039-
return 0;
28040-
}
28041-
return signature.minArgumentCount;
28079+
return signature.resolvedMinArgumentCount;
2804228080
}
2804328081

2804428082
function hasEffectiveRestParameter(signature: Signature) {

src/compiler/core.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,14 +1304,14 @@ namespace ts {
13041304
return values;
13051305
}
13061306

1307-
const _entries = Object.entries ? Object.entries : <T>(obj: MapLike<T>) => {
1307+
const _entries = Object.entries || (<T>(obj: MapLike<T>) => {
13081308
const keys = getOwnKeys(obj);
13091309
const result: [string, T][] = Array(keys.length);
1310-
for (const key of keys) {
1311-
result.push([key, obj[key]]);
1310+
for (let i = 0; i < keys.length; i++) {
1311+
result[i] = [keys[i], obj[keys[i]]];
13121312
}
13131313
return result;
1314-
};
1314+
});
13151315

13161316
export function getEntries<T>(obj: MapLike<T>): [string, T][] {
13171317
return obj ? _entries(obj) : [];

src/compiler/debug.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,25 @@ namespace ts {
413413
export function enableDebugInfo() {
414414
if (isDebugInfoEnabled) return;
415415

416+
// avoid recomputing
417+
let weakTypeTextMap: WeakMap<Type, string> | undefined;
418+
let weakNodeTextMap: WeakMap<Node, string> | undefined;
419+
420+
function getWeakTypeTextMap() {
421+
if (weakTypeTextMap === undefined) {
422+
if (typeof WeakMap === "function") weakTypeTextMap = new WeakMap();
423+
}
424+
return weakTypeTextMap;
425+
}
426+
427+
function getWeakNodeTextMap() {
428+
if (weakNodeTextMap === undefined) {
429+
if (typeof WeakMap === "function") weakNodeTextMap = new WeakMap();
430+
}
431+
return weakNodeTextMap;
432+
}
433+
434+
416435
// Add additional properties in debug mode to assist with debugging.
417436
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
418437
__debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
@@ -421,7 +440,18 @@ namespace ts {
421440
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
422441
__debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } },
423442
__debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
424-
__debugTypeToString: { value(this: Type) { return this.checker.typeToString(this); } },
443+
__debugTypeToString: {
444+
value(this: Type) {
445+
// avoid recomputing
446+
const map = getWeakTypeTextMap();
447+
let text = map?.get(this);
448+
if (text === undefined) {
449+
text = this.checker.typeToString(this);
450+
map?.set(this, text);
451+
}
452+
return text;
453+
}
454+
},
425455
});
426456

427457
const nodeConstructors = [
@@ -443,9 +473,16 @@ namespace ts {
443473
__debugGetText: {
444474
value(this: Node, includeTrivia?: boolean) {
445475
if (nodeIsSynthesized(this)) return "";
446-
const parseNode = getParseTreeNode(this);
447-
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
448-
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode!, includeTrivia) : "";
476+
// avoid recomputing
477+
const map = getWeakNodeTextMap();
478+
let text = map?.get(this);
479+
if (text === undefined) {
480+
const parseNode = getParseTreeNode(this);
481+
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
482+
text = sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode!, includeTrivia) : "";
483+
map?.set(this, text);
484+
}
485+
return text;
449486
}
450487
}
451488
});

src/compiler/diagnosticMessages.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,10 @@
11801180
"category": "Error",
11811181
"code": 1388
11821182
},
1183+
"'{0}' is not allowed as a variable declaration name.": {
1184+
"category": "Error",
1185+
"code": 1389
1186+
},
11831187

11841188
"The types of '{0}' are incompatible between these types.": {
11851189
"category": "Error",
@@ -2748,7 +2752,7 @@
27482752
"category": "Error",
27492753
"code": 2723
27502754
},
2751-
"Module '{0}' has no exported member '{1}'. Did you mean '{2}'?": {
2755+
"'{0}' has no exported member named '{1}'. Did you mean '{2}'?": {
27522756
"category": "Error",
27532757
"code": 2724
27542758
},
@@ -3025,7 +3029,6 @@
30253029
"code": 2792
30263030
},
30273031

3028-
30293032
"Import declaration '{0}' is using private name '{1}'.": {
30303033
"category": "Error",
30313034
"code": 4000

0 commit comments

Comments
 (0)