Skip to content

Commit 6b90e6e

Browse files
committed
Merge branch 'master' into bug/37813
2 parents a15ea78 + 795a5c8 commit 6b90e6e

File tree

59 files changed

+1161
-138
lines changed

Some content is hidden

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

59 files changed

+1161
-138
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616

1717
strategy:
1818
matrix:
19-
node-version: [8.x, 10.x, 12.x]
19+
node-version: [10.x, 12.x, 13.x]
2020

2121
steps:
2222
- uses: actions/checkout@v1
@@ -35,6 +35,7 @@ jobs:
3535
npm install
3636
npm update
3737
npm test
38+
3839
- name: Validate the browser can import TypeScript
3940
run: gulp test-browser-integration
4041

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
"mocha-fivemat-progress-reporter": "latest",
8888
"ms": "latest",
8989
"node-fetch": "^2.6.0",
90-
"playwright": "latest",
90+
"playwright": "0.12.1",
9191
"plugin-error": "latest",
9292
"pretty-hrtime": "^1.0.3",
9393
"prex": "^0.4.3",

src/compiler/checker.ts

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ namespace ts {
196196
Source = 1 << 0,
197197
Target = 1 << 1,
198198
PropertyCheck = 1 << 2,
199+
InPropertyCheck = 1 << 3,
199200
}
200201

201202
const enum MappedTypeModifiers {
@@ -6132,7 +6133,8 @@ namespace ts {
61326133
// Each overload becomes a separate function declaration, in order
61336134
const decl = signatureToSignatureDeclarationHelper(sig, SyntaxKind.FunctionDeclaration, context, includePrivateSymbol, bundled) as FunctionDeclaration;
61346135
decl.name = createIdentifier(localName);
6135-
addResult(setTextRange(decl, sig.declaration), modifierFlags);
6136+
// for expressions assigned to `var`s, use the `var` as the text range
6137+
addResult(setTextRange(decl, sig.declaration && isVariableDeclaration(sig.declaration.parent) && sig.declaration.parent.parent || sig.declaration), modifierFlags);
61366138
}
61376139
// Module symbol emit will take care of module-y members, provided it has exports
61386140
if (!(symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && !!symbol.exports && !!symbol.exports.size)) {
@@ -6210,14 +6212,18 @@ namespace ts {
62106212
];
62116213
const symbolProps = getPropertiesOfType(classType);
62126214
const publicSymbolProps = filter(symbolProps, s => {
6215+
// `valueDeclaration` could be undefined if inherited from
6216+
// a union/intersection base type, but inherited properties
6217+
// don't matter here.
62136218
const valueDecl = s.valueDeclaration;
6214-
Debug.assertIsDefined(valueDecl);
6215-
return !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
6219+
return valueDecl && !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
62166220
});
62176221
const hasPrivateIdentifier = some(symbolProps, s => {
6222+
// `valueDeclaration` could be undefined if inherited from
6223+
// a union/intersection base type, but inherited properties
6224+
// don't matter here.
62186225
const valueDecl = s.valueDeclaration;
6219-
Debug.assertIsDefined(valueDecl);
6220-
return isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
6226+
return valueDecl && isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
62216227
});
62226228
// Boil down all private properties into a single one.
62236229
const privateProperties = hasPrivateIdentifier ?
@@ -10419,7 +10425,7 @@ namespace ts {
1041910425
if (!firstValueDeclaration) {
1042010426
firstValueDeclaration = prop.valueDeclaration;
1042110427
}
10422-
else if (prop.valueDeclaration !== firstValueDeclaration) {
10428+
else if (prop.valueDeclaration && prop.valueDeclaration !== firstValueDeclaration) {
1042310429
hasNonUniformValueDeclaration = true;
1042410430
}
1042510431
declarations = addRange(declarations, prop.declarations);
@@ -14545,6 +14551,16 @@ namespace ts {
1454514551
}
1454614552
}
1454714553

14554+
function checkExpressionForMutableLocationWithContextualType(next: Expression, sourcePropType: Type) {
14555+
next.contextualType = sourcePropType;
14556+
try {
14557+
return checkExpressionForMutableLocation(next, CheckMode.Contextual, sourcePropType);
14558+
}
14559+
finally {
14560+
next.contextualType = undefined;
14561+
}
14562+
}
14563+
1454814564
type ElaborationIterator = IterableIterator<{ errorNode: Node, innerExpression: Expression | undefined, nameType: Type, errorMessage?: DiagnosticMessage | undefined }>;
1454914565
/**
1455014566
* For every element returned from the iterator, checks that element to issue an error on a property of that element's type
@@ -14575,7 +14591,7 @@ namespace ts {
1457514591
// Issue error on the prop itself, since the prop couldn't elaborate the error
1457614592
const resultObj: { errors?: Diagnostic[] } = errorOutputContainer || {};
1457714593
// Use the expression type, if available
14578-
const specificSource = next ? checkExpressionForMutableLocation(next, CheckMode.Normal, sourcePropType) : sourcePropType;
14594+
const specificSource = next ? checkExpressionForMutableLocationWithContextualType(next, sourcePropType) : sourcePropType;
1457914595
const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, containingMessageChain, resultObj);
1458014596
if (result && specificSource !== sourcePropType) {
1458114597
// If for whatever reason the expression type doesn't yield an error, make sure we still issue an error on the sourcePropType
@@ -15230,6 +15246,7 @@ namespace ts {
1523015246
let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
1523115247
let lastSkippedInfo: [Type, Type] | undefined;
1523215248
let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = [];
15249+
let inPropertyCheck = false;
1523315250

1523415251
Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
1523515252

@@ -15238,7 +15255,7 @@ namespace ts {
1523815255
reportIncompatibleStack();
1523915256
}
1524015257
if (overflow) {
15241-
const diag = error(errorNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
15258+
const diag = error(errorNode || currentNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
1524215259
if (errorOutputContainer) {
1524315260
(errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
1524415261
}
@@ -15665,10 +15682,15 @@ namespace ts {
1566515682
// function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
1566615683
// x = y; // Mismatched property in source intersection
1566715684
// }
15668-
if (result && (
15685+
//
15686+
// We suppress recursive intersection property checks because they can generate lots of work when relating
15687+
// recursive intersections that are structurally similar but not exactly identical. See #37854.
15688+
if (result && !inPropertyCheck && (
1566915689
target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
1567015690
isNonGenericObjectType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((<IntersectionType>source).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
15691+
inPropertyCheck = true;
1567115692
result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck);
15693+
inPropertyCheck = false;
1567215694
}
1567315695

1567415696
if (!result && reportErrors) {
@@ -15965,7 +15987,7 @@ namespace ts {
1596515987
if (overflow) {
1596615988
return Ternary.False;
1596715989
}
15968-
const id = getRelationKey(source, target, intersectionState, relation);
15990+
const id = getRelationKey(source, target, intersectionState | (inPropertyCheck ? IntersectionState.InPropertyCheck : 0), relation);
1596915991
const entry = relation.get(id);
1597015992
if (entry !== undefined) {
1597115993
if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Reported)) {
@@ -27243,7 +27265,7 @@ namespace ts {
2724327265
}
2724427266

2724527267
const functionFlags = getFunctionFlags(func);
27246-
const type = returnType && getReturnOrPromisedType(returnType, functionFlags);
27268+
const type = returnType && unwrapReturnType(returnType, functionFlags);
2724727269

2724827270
// Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
2724927271
if (type && maybeTypeOfKind(type, TypeFlags.Any | TypeFlags.Void)) {
@@ -27363,14 +27385,6 @@ namespace ts {
2736327385
}
2736427386
}
2736527387

27366-
function getReturnOrPromisedType(type: Type | undefined, functionFlags: FunctionFlags) {
27367-
const isGenerator = !!(functionFlags & FunctionFlags.Generator);
27368-
const isAsync = !!(functionFlags & FunctionFlags.Async);
27369-
return type && isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, type, isAsync) || errorType :
27370-
type && isAsync ? getAwaitedType(type) || errorType :
27371-
type;
27372-
}
27373-
2737427388
function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
2737527389
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
2737627390

@@ -27398,7 +27412,7 @@ namespace ts {
2739827412
// check assignability of the awaited type of the expression body against the promised type of
2739927413
// its return type annotation.
2740027414
const exprType = checkExpression(node.body);
27401-
const returnOrPromisedType = getReturnOrPromisedType(returnType, functionFlags);
27415+
const returnOrPromisedType = returnType && unwrapReturnType(returnType, functionFlags);
2740227416
if (returnOrPromisedType) {
2740327417
if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function
2740427418
const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
@@ -32686,8 +32700,8 @@ namespace ts {
3268632700
function unwrapReturnType(returnType: Type, functionFlags: FunctionFlags) {
3268732701
const isGenerator = !!(functionFlags & FunctionFlags.Generator);
3268832702
const isAsync = !!(functionFlags & FunctionFlags.Async);
32689-
return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) || errorType :
32690-
isAsync ? getPromisedTypeOfPromise(returnType) || errorType :
32703+
return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) ?? errorType :
32704+
isAsync ? getAwaitedType(returnType) ?? errorType :
3269132705
returnType;
3269232706
}
3269332707

@@ -32724,7 +32738,7 @@ namespace ts {
3272432738
}
3272532739
}
3272632740
else if (getReturnTypeFromAnnotation(func)) {
32727-
const unwrappedReturnType = unwrapReturnType(returnType, functionFlags);
32741+
const unwrappedReturnType = unwrapReturnType(returnType, functionFlags) ?? returnType;
3272832742
const unwrappedExprType = functionFlags & FunctionFlags.Async
3272932743
? checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
3273032744
: exprType;
@@ -32936,6 +32950,10 @@ namespace ts {
3293632950
const propDeclaration = prop.valueDeclaration;
3293732951
const name = propDeclaration && getNameOfDeclaration(propDeclaration);
3293832952

32953+
if (name && isPrivateIdentifier(name)) {
32954+
return;
32955+
}
32956+
3293932957
// index is numeric and property name is not valid numeric literal
3294032958
if (indexKind === IndexKind.Number && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) {
3294132959
return;
@@ -34015,7 +34033,7 @@ namespace ts {
3401534033
return false;
3401634034
}
3401734035
if (inAmbientExternalModule && isExternalModuleNameRelative(moduleName.text)) {
34018-
// we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration
34036+
// we have already reported errors on top level imports/exports in external module augmentations in checkModuleDeclaration
3401934037
// no need to do this again.
3402034038
if (!isTopLevelInExternalModuleAugmentation(node)) {
3402134039
// TypeScript 1.0 spec (April 2013): 12.1.6
@@ -34151,16 +34169,10 @@ namespace ts {
3415134169

3415234170
checkGrammarExportDeclaration(node);
3415334171
if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
34154-
if (node.exportClause) {
34172+
if (node.exportClause && !isNamespaceExport(node.exportClause)) {
3415534173
// export { x, y }
3415634174
// export { x, y } from "foo"
34157-
if (isNamedExports(node.exportClause)) {
34158-
forEach(node.exportClause.elements, checkExportSpecifier);
34159-
}
34160-
else if(!isNamespaceExport(node.exportClause)) {
34161-
checkImportBinding(node.exportClause);
34162-
}
34163-
34175+
forEach(node.exportClause.elements, checkExportSpecifier);
3416434176
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent);
3416534177
const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock &&
3416634178
!node.moduleSpecifier && node.flags & NodeFlags.Ambient;
@@ -34174,7 +34186,9 @@ namespace ts {
3417434186
if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
3417534187
error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
3417634188
}
34177-
34189+
else if (node.exportClause) {
34190+
checkAliasSymbol(node.exportClause);
34191+
}
3417834192
if (moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) {
3417934193
checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar);
3418034194
}

src/compiler/factoryPublic.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,9 +1555,11 @@ namespace ts {
15551555
export function createYield(expression?: Expression): YieldExpression;
15561556
export function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression;
15571557
export function createYield(asteriskTokenOrExpression?: AsteriskToken | undefined | Expression, expression?: Expression) {
1558+
const asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === SyntaxKind.AsteriskToken ? <AsteriskToken>asteriskTokenOrExpression : undefined;
1559+
expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : expression;
15581560
const node = <YieldExpression>createSynthesizedNode(SyntaxKind.YieldExpression);
1559-
node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === SyntaxKind.AsteriskToken ? <AsteriskToken>asteriskTokenOrExpression : undefined;
1560-
node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : expression;
1561+
node.asteriskToken = asteriskToken;
1562+
node.expression = expression && parenthesizeExpressionForList(expression);
15611563
return node;
15621564
}
15631565

src/compiler/path.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ namespace ts {
527527
*
528528
* ```ts
529529
* getNormalizedPathComponents("to/dir/../file.ext", "/path/") === ["/", "path", "to", "file.ext"]
530+
* ```
530531
*/
531532
export function getNormalizedPathComponents(path: string, currentDirectory: string | undefined) {
532533
return reducePathComponents(getPathComponents(path, currentDirectory));
@@ -856,4 +857,4 @@ namespace ts {
856857
export function isNodeModulesDirectory(dirPath: Path) {
857858
return endsWith(dirPath, "/node_modules");
858859
}
859-
}
860+
}

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3444,7 +3444,7 @@ namespace ts {
34443444
const doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
34453445
const singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
34463446
// Template strings should be preserved as much as possible
3447-
const backtickQuoteEscapedCharsRegExp = /[\\\`]/g;
3447+
const backtickQuoteEscapedCharsRegExp = /[\\`]/g;
34483448
const escapedCharsMap = createMapFromTemplate({
34493449
"\t": "\\t",
34503450
"\v": "\\v",

0 commit comments

Comments
 (0)